Skip to content

Commit

Permalink
Merge branch 'bringup/esp32h2_light_sleep_for_rebase' into 'master'
Browse files Browse the repository at this point in the history
esp32h2: support light_sleep

Closes IDF-6266 and IDF-7359

See merge request espressif/esp-idf!23567
  • Loading branch information
10086loutianhao committed Jun 28, 2023
2 parents f637198 + c7c937e commit 7c2ac1f
Show file tree
Hide file tree
Showing 60 changed files with 1,650 additions and 731 deletions.
18 changes: 2 additions & 16 deletions components/bootloader_support/src/bootloader_random.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "esp_cpu.h"
#include "soc/wdev_reg.h"

#if defined CONFIG_IDF_TARGET_ESP32C6
#if SOC_LP_TIMER_SUPPORTED
#include "hal/lp_timer_hal.h"
#endif

Expand All @@ -34,20 +34,6 @@
#define RNG_CPU_WAIT_CYCLE_NUM (80 * 23) /* 45 KHz reading frequency is the maximum we have tested so far on S3 */
#endif

#if defined CONFIG_IDF_TARGET_ESP32H2

// TODO: temporary definition until IDF-6270 is implemented
#include "soc/lp_timer_reg.h"

static inline uint32_t lp_timer_hal_get_cycle_count(void)
{
REG_SET_BIT(LP_TIMER_UPDATE_REG, LP_TIMER_MAIN_TIMER_UPDATE);

uint32_t lo = REG_GET_FIELD(LP_TIMER_MAIN_BUF0_LOW_REG, LP_TIMER_MAIN_TIMER_BUF0_LOW);
return lo;
}
#endif

__attribute__((weak)) void bootloader_fill_random(void *buffer, size_t length)
{
uint8_t *buffer_bytes = (uint8_t *)buffer;
Expand All @@ -57,7 +43,7 @@ static inline uint32_t lp_timer_hal_get_cycle_count(void)
assert(buffer != NULL);

for (size_t i = 0; i < length; i++) {
#if (defined CONFIG_IDF_TARGET_ESP32C6 || defined CONFIG_IDF_TARGET_ESP32H2)
#if SOC_LP_TIMER_SUPPORTED
random = REG_READ(WDEV_RND_REG);
start = esp_cpu_get_cycle_count();
do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ static void bootloader_super_wdt_auto_feed(void)

static inline void bootloader_hardware_init(void)
{
// TODO: IDF-6267
/* Enable analog i2c master clock */
SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN);
}
Expand Down
4 changes: 0 additions & 4 deletions components/driver/ledc/ledc.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,9 +440,7 @@ static uint32_t ledc_auto_clk_divisor(ledc_mode_t speed_mode, int freq_hz, uint3
return ret;
}

#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6267 Remove when H2 light sleep supported
extern void esp_sleep_periph_use_8m(bool use_or_not);
#endif

/**
* @brief Function setting the LEDC timer divisor with the given source clock,
Expand Down Expand Up @@ -559,9 +557,7 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
ESP_LOGD(LEDC_TAG, "In slow speed mode, global clk set: %d", glb_clk);

/* keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6267 Remove when H2 light sleep supported
esp_sleep_periph_use_8m(glb_clk == LEDC_SLOW_CLK_RC_FAST);
#endif
}

/* The divisor is correct, we can write in the hardware. */
Expand Down
2 changes: 0 additions & 2 deletions components/driver/test_apps/gpio/main/test_gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,6 @@ TEST_CASE("GPIO_USB_DP_pin_pullup_disable_test", "[gpio]")
}
#endif //SOC_USB_SERIAL_JTAG_SUPPORTED

#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2) // TODO: IDF-6267 Remove when light sleep is supported
// Ignored in CI because it needs manually connect TEST_GPIO_INPUT_LEVEL_LOW_PIN to 3.3v to wake up from light sleep
TEST_CASE("GPIO_light_sleep_wake_up_test", "[gpio][ignore]")
{
Expand All @@ -861,4 +860,3 @@ TEST_CASE("GPIO_light_sleep_wake_up_test", "[gpio][ignore]")
printf("Waked up from light sleep\n");
TEST_ASSERT(esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_GPIO);
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(...)
5 changes: 1 addition & 4 deletions components/esp_hw_support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,7 @@ if(NOT BOOTLOADER_BUILD)

if(CONFIG_IDF_TARGET_ESP32H2)
list(REMOVE_ITEM srcs
"sleep_cpu.c" # TODO: IDF-6267
"sleep_modes.c" # TODO: IDF-6267
"sleep_wake_stub.c" # TODO: IDF-6267
"sleep_gpio.c" # TODO: IDF-6267
"sleep_wake_stub.c" # TODO: IDF-6268
)
endif()
else()
Expand Down
7 changes: 4 additions & 3 deletions components/esp_hw_support/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,12 @@ menu "Hardware Settings"

config ESP_SLEEP_GPIO_RESET_WORKAROUND
bool "light sleep GPIO reset workaround"
default y if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6
default y if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || \
IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2
select PM_SLP_DISABLE_GPIO if FREERTOS_USE_TICKLESS_IDLE
help
esp32c2, esp32c3 and esp32s3 will reset at wake-up if GPIO is received a small electrostatic
pulse during light sleep, with specific condition
esp32c2, esp32c3, esp32s3, esp32c6 and esp32h2 will reset at wake-up if GPIO is received
a small electrostatic pulse during light sleep, with specific condition

- GPIO needs to be configured as input-mode only
- The pin receives a small electrostatic pulse, and reset occurs when the pulse
Expand Down
18 changes: 2 additions & 16 deletions components/esp_hw_support/hw_random.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "soc/wdev_reg.h"
#include "esp_private/esp_clk.h"

#if defined CONFIG_IDF_TARGET_ESP32C6
#if SOC_LP_TIMER_SUPPORTED
#include "hal/lp_timer_hal.h"
#endif

Expand All @@ -34,20 +34,6 @@
#define APB_CYCLE_WAIT_NUM (16)
#endif

#if defined CONFIG_IDF_TARGET_ESP32H2

// TODO: temporary definition until IDF-6270 is implemented
#include "soc/lp_timer_reg.h"

static uint32_t IRAM_ATTR lp_timer_hal_get_cycle_count(void)
{
REG_SET_BIT(LP_TIMER_UPDATE_REG, LP_TIMER_MAIN_TIMER_UPDATE);

uint32_t lo = REG_GET_FIELD(LP_TIMER_MAIN_BUF0_LOW_REG, LP_TIMER_MAIN_TIMER_BUF0_LOW);
return lo;
}
#endif

uint32_t IRAM_ATTR esp_random(void)
{
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
Expand All @@ -73,7 +59,7 @@ uint32_t IRAM_ATTR esp_random(void)
static uint32_t last_ccount = 0;
uint32_t ccount;
uint32_t result = 0;
#if (defined CONFIG_IDF_TARGET_ESP32C6 || defined CONFIG_IDF_TARGET_ESP32H2)
#if SOC_LP_TIMER_SUPPORTED
for (size_t i = 0; i < sizeof(result); i++) {
do {
ccount = esp_cpu_get_cycle_count();
Expand Down
20 changes: 20 additions & 0 deletions components/esp_hw_support/include/esp_private/esp_pau.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ extern "C" {
*/
void pau_regdma_set_entry_link_addr(pau_regdma_link_addr_t *link_entries);

#if SOC_PM_SUPPORT_PMU_MODEM_STATE
/**
* @brief Set the address of WiFi MAC REGDMA Link in modem state
* @param link_addr linked lists address
Expand All @@ -40,6 +41,25 @@ void pau_regdma_trigger_modem_link_backup(void);
* @brief Software trigger regdma to perform modem link restore
*/
void pau_regdma_trigger_modem_link_restore(void);
#endif

#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG
/**
* @brief Set the address of system REGDMA Link in active state
* @param link_addr linked lists address
*/
void pau_regdma_set_system_link_addr(void *link_addr);

/**
* @brief Software trigger regdma to perform system link backup
*/
void pau_regdma_trigger_system_link_backup(void);

/**
* @brief Software trigger regdma to perform system link restore
*/
void pau_regdma_trigger_system_link_restore(void);
#endif

/**
* @brief Set the address of extra REGDMA Link in active state
Expand Down
6 changes: 5 additions & 1 deletion components/esp_hw_support/include/esp_private/esp_pmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,11 @@ extern "C" {
#define PMU_SLEEP_PD_MODEM BIT(2)
#define PMU_SLEEP_PD_HP_PERIPH BIT(3)
#define PMU_SLEEP_PD_CPU BIT(4)
#define PMU_SLEEP_PD_AON BIT(5)

#if SOC_PM_SUPPORT_HP_AON_PD
#define PMU_SLEEP_PD_HP_AON BIT(5)
#endif

#define PMU_SLEEP_PD_MEM_G0 BIT(6)
#define PMU_SLEEP_PD_MEM_G1 BIT(7)
#define PMU_SLEEP_PD_MEM_G2 BIT(8)
Expand Down
10 changes: 10 additions & 0 deletions components/esp_hw_support/include/esp_private/sleep_retention.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ void sleep_retention_do_extra_retention(bool backup_or_restore);
*/
uint32_t sleep_retention_get_modules(void);

#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG
/**
* @brief Software trigger REGDMA to do system linked list retention
*
* @param backup_or_restore true for backup register context to memory
* or false for restore to register from memory
*/
void sleep_retention_do_system_retention(bool backup_or_restore);
#endif

#endif // SOC_PAU_SUPPORTED

#ifdef __cplusplus
Expand Down
8 changes: 0 additions & 8 deletions components/esp_hw_support/modem_clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,6 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = src;
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);

#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6267
/* The power domain of the low-power clock source required by the modem
* module remains powered on during sleep */
esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( \
Expand All @@ -335,9 +334,6 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
: ESP_PD_DOMAIN_MAX);
esp_sleep_pd_config(pd_domain, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(pu_domain, ESP_PD_OPTION_ON);
#else
(void)last_src; // Only for bypass compile warning, delete if IDF-6267 resloved
#endif //!CONFIG_IDF_TARGET_ESP32H2
}

void modem_clock_deselect_lp_clock_source(periph_module_t module)
Expand Down Expand Up @@ -370,15 +366,11 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module)
MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = MODEM_CLOCK_LPCLK_SRC_INVALID;
portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);

#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6267
esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( \
(last_src == MODEM_CLOCK_LPCLK_SRC_RC_FAST) ? ESP_PD_DOMAIN_RC_FAST \
: (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) ? ESP_PD_DOMAIN_XTAL \
: (last_src == MODEM_CLOCK_LPCLK_SRC_RC32K) ? ESP_PD_DOMAIN_RC32K \
: (last_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K \
: ESP_PD_DOMAIN_MAX);
esp_sleep_pd_config(pd_domain, ESP_PD_OPTION_OFF);
#else
(void)last_src; // Only for bypass compile warning, delete if IDF-6267 resloved
#endif //!CONFIG_IDF_TARGET_ESP32H2
}
2 changes: 1 addition & 1 deletion components/esp_hw_support/port/esp32c6/pmu_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
// for bypass reserved power domain
const pmu_hp_power_domain_t pmu_hp_domains[] = {
PMU_HP_PD_TOP,
PMU_HP_PD_AON,
PMU_HP_PD_HP_AON,
PMU_HP_PD_CPU,
PMU_HP_PD_WIFI
};
Expand Down
14 changes: 2 additions & 12 deletions components/esp_hw_support/port/esp32c6/pmu_sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default(
param->lp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_up_wait_time_us, fastclk_period);

if (power->hp_sys.xtal.xpd_xtal) {
param->hp_lp.xtal_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.xtal_wait_stable_time_us, fastclk_period);
} else {
param->hp_lp.xtal_stable_wait_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.xtal_wait_stable_time_us, slowclk_period);
} else {
param->hp_lp.xtal_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.xtal_wait_stable_time_us, fastclk_period);
}
return param;
}
Expand Down Expand Up @@ -196,11 +196,6 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi
pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].clk_power.val);
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtal);

if (dslp) {
// TODO: IDF-5349
} else {
}
}

static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_config_t *dig)
Expand Down Expand Up @@ -234,11 +229,6 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con
pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias);
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b);

if (dslp) {
// TODO: IDF-5349
} else {
}
}

static void pmu_sleep_param_init(pmu_context_t *ctx, const pmu_sleep_param_config_t *param, bool dslp)
Expand Down
Loading

0 comments on commit 7c2ac1f

Please sign in to comment.