From d81a93ae4c137575a2ae2bdc73ecffc65f52f20b Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Thu, 7 Jan 2021 22:44:33 +0800 Subject: [PATCH 1/3] esp32c3: Adds support BROWNOUT reset --- components/esp32c3/Kconfig | 20 ++++++++----------- components/esp_common/src/brownout.c | 9 ++++++++- components/esp_system/startup.c | 5 ++++- .../esp_system/test/test_reset_reason.c | 2 -- components/hal/esp32c3/brownout_hal.c | 15 +++++++++++--- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/components/esp32c3/Kconfig b/components/esp32c3/Kconfig index e72f54ec2c..cd54d9c192 100644 --- a/components/esp32c3/Kconfig +++ b/components/esp32c3/Kconfig @@ -78,9 +78,8 @@ menu "ESP32C3-Specific" e.g. GCOV data dump. config ESP32C3_BROWNOUT_DET - # TODO ESP32-C3 IDF-2397 bool - default n + default y help The ESP32-S3 has a built-in brownout detector which can detect if the voltage is lower than a specific value. If this happens, it will reset the chip in order to prevent unintended @@ -93,29 +92,26 @@ menu "ESP32C3-Specific" help The brownout detector will reset the chip when the supply voltage is approximately below this level. Note that there may be some variation of brownout voltage level - between each ESP3-S3 chip. + between each chip. #The voltage levels here are estimates, more work needs to be done to figure out the exact voltages #of the brownout threshold levels. config ESP32C3_BROWNOUT_DET_LVL_SEL_7 - bool "2.44V" + bool "2.51V" config ESP32C3_BROWNOUT_DET_LVL_SEL_6 - bool "2.56V" + bool "2.64V" config ESP32C3_BROWNOUT_DET_LVL_SEL_5 - bool "2.67V" + bool "2.76V" config ESP32C3_BROWNOUT_DET_LVL_SEL_4 - bool "2.84V" + bool "2.92V" config ESP32C3_BROWNOUT_DET_LVL_SEL_3 - bool "2.98V" + bool "3.10V" config ESP32C3_BROWNOUT_DET_LVL_SEL_2 - bool "3.19V" - config ESP32C3_BROWNOUT_DET_LVL_SEL_1 - bool "3.30V" + bool "3.27V" endchoice config ESP32C3_BROWNOUT_DET_LVL int - default 1 if ESP32C3_BROWNOUT_DET_LVL_SEL_1 default 2 if ESP32C3_BROWNOUT_DET_LVL_SEL_2 default 3 if ESP32C3_BROWNOUT_DET_LVL_SEL_3 default 4 if ESP32C3_BROWNOUT_DET_LVL_SEL_4 diff --git a/components/esp_common/src/brownout.c b/components/esp_common/src/brownout.c index 990f3938d0..f64b3d0b29 100644 --- a/components/esp_common/src/brownout.c +++ b/components/esp_common/src/brownout.c @@ -35,6 +35,10 @@ #define BROWNOUT_DET_LVL CONFIG_ESP32_BROWNOUT_DET_LVL #elif defined(CONFIG_ESP32S2_BROWNOUT_DET_LVL) #define BROWNOUT_DET_LVL CONFIG_ESP32S2_BROWNOUT_DET_LVL +#elif defined(CONFIG_ESP32S3_BROWNOUT_DET_LVL) +#define BROWNOUT_DET_LVL CONFIG_ESP32S3_BROWNOUT_DET_LVL +#elif defined(CONFIG_ESP32C3_BROWNOUT_DET_LVL) +#define BROWNOUT_DET_LVL CONFIG_ESP32C3_BROWNOUT_DET_LVL #else #define BROWNOUT_DET_LVL 0 #endif @@ -45,7 +49,7 @@ #define BROWNOUT_RESET_EN false #endif // SOC_BROWNOUT_RESET_SUPPORTED - +#ifndef SOC_BROWNOUT_RESET_SUPPORTED static void rtc_brownout_isr_handler(void *arg) { /* Normally RTC ISR clears the interrupt flag after the application-supplied @@ -61,6 +65,7 @@ static void rtc_brownout_isr_handler(void *arg) esp_rom_printf("\r\nBrownout detector was triggered\r\n\r\n"); esp_restart_noos(); } +#endif // not SOC_BROWNOUT_RESET_SUPPORTED void esp_brownout_init(void) { @@ -74,7 +79,9 @@ void esp_brownout_init(void) brownout_hal_config(&cfg); +#ifndef SOC_BROWNOUT_RESET_SUPPORTED rtc_isr_register(rtc_brownout_isr_handler, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M); brownout_hal_intr_enable(true); +#endif // not SOC_BROWNOUT_RESET_SUPPORTED } diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index 2f5a9040f5..3ad549d267 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -242,7 +242,10 @@ static void do_core_init(void) #endif } -#if CONFIG_ESP32_BROWNOUT_DET || CONFIG_ESP32S2_BROWNOUT_DET +#if CONFIG_ESP32_BROWNOUT_DET || \ + CONFIG_ESP32S2_BROWNOUT_DET || \ + CONFIG_ESP32S3_BROWNOUT_DET || \ + CONFIG_ESP32C3_BROWNOUT_DET // [refactor-todo] leads to call chain rtc_is_register (driver) -> esp_intr_alloc (esp32/esp32s2) -> // malloc (newlib) -> heap_caps_malloc (heap), so heap must be at least initialized esp_brownout_init(); diff --git a/components/esp_system/test/test_reset_reason.c b/components/esp_system/test/test_reset_reason.c index 7819b6e6bb..328bba4a41 100644 --- a/components/esp_system/test/test_reset_reason.c +++ b/components/esp_system/test/test_reset_reason.c @@ -264,7 +264,6 @@ TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_WDT after RTC watchdog", check_reset_reason_any_wdt); -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) // TODO ESP32-C3 IDF-2397 static void do_brownout(void) { setup_values(); @@ -289,7 +288,6 @@ TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_BROWNOUT after brownout event", "[reset_reason][ignore][reset="BROWNOUT"]", do_brownout, check_reset_reason_brownout); -#endif // TODO ESP32-C3 IDF-2397 #ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY diff --git a/components/hal/esp32c3/brownout_hal.c b/components/hal/esp32c3/brownout_hal.c index 1fc22420b1..5dac36f067 100644 --- a/components/hal/esp32c3/brownout_hal.c +++ b/components/hal/esp32c3/brownout_hal.c @@ -22,15 +22,24 @@ void brownout_hal_config(const brownout_hal_config_t *cfg) { - // TODO ESP32-C3 IDF-2397 + REGI2C_WRITE_MASK(I2C_BOD, I2C_BOD_THRESHOLD, cfg->threshold); + typeof(RTCCNTL.brown_out) brown_out_reg = { + .close_flash_ena = cfg->flash_power_down, + .pd_rf_ena = cfg->rf_power_down, + .rst_wait = 0x3ff, + .rst_ena = cfg->reset_enabled, + .ena = cfg->enabled, + .rst_sel = 1, + }; + RTCCNTL.brown_out = brown_out_reg; } void brownout_hal_intr_enable(bool enable) { - // TODO ESP32-C3 IDF-2397 + RTCCNTL.int_ena.rtc_brown_out = enable; } void brownout_hal_intr_clear(void) { - // TODO ESP32-C3 IDF-2397 + RTCCNTL.int_clr.rtc_brown_out = 1; } From f58c2963368525de49b743189691a301b5c204f6 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Fri, 8 Jan 2021 19:48:14 +0800 Subject: [PATCH 2/3] esp32s2: BROWNOUT reset reason is set directly without using the brownout ISR --- components/hal/esp32s2/brownout_hal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/hal/esp32s2/brownout_hal.c b/components/hal/esp32s2/brownout_hal.c index 0658304d65..a09e1ea4ea 100644 --- a/components/hal/esp32s2/brownout_hal.c +++ b/components/hal/esp32s2/brownout_hal.c @@ -31,6 +31,7 @@ void brownout_hal_config(const brownout_hal_config_t *cfg) .rst_wait = 0x3ff, .rst_ena = cfg->reset_enabled, .ena = cfg->enabled, + .rst_sel = 1, }; RTCCNTL.brown_out = brown_out_reg; } From e62d4a6b8149ac5755d9aac55e85e2d79bebb2fe Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Fri, 8 Jan 2021 19:51:30 +0800 Subject: [PATCH 3/3] esp32s3: BROWNOUT reset reason is set directly without using the brownout ISR --- components/hal/esp32s3/brownout_hal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/hal/esp32s3/brownout_hal.c b/components/hal/esp32s3/brownout_hal.c index d85d47341e..99bd5e52bf 100644 --- a/components/hal/esp32s3/brownout_hal.c +++ b/components/hal/esp32s3/brownout_hal.c @@ -30,6 +30,7 @@ void brownout_hal_config(const brownout_hal_config_t *cfg) .rst_wait = 0x3ff, .rst_ena = cfg->reset_enabled, .ena = cfg->enabled, + .rst_sel = 1, }; RTCCNTL.brown_out = brown_out_reg; }