diff --git a/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c b/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c index 2531cec91c..0f53f259ad 100644 --- a/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c +++ b/components/bootloader_support/src/esp32c5/bootloader_esp32c5.c @@ -42,6 +42,7 @@ #include "hal/efuse_hal.h" #include "hal/lpwdt_ll.h" #include "hal/regi2c_ctrl_ll.h" +#include "hal/brownout_ll.h" static const char *TAG = "boot.esp32c5"; @@ -94,9 +95,8 @@ static inline void bootloader_ana_reset_config(void) // TODO: [ESP32C5] IDF-8650 //Enable super WDT reset. // bootloader_ana_super_wdt_reset_config(true); - // TODO: [ESP32C5] IDF-8647 - //Enable BOD reset TODO: [ESP32C5] IDF-8667 - // brownout_ll_ana_reset_enable(true); + //Enable BOD reset (mode1) + brownout_ll_ana_reset_enable(true); } esp_err_t bootloader_init(void) diff --git a/components/esp_system/port/brownout.c b/components/esp_system/port/brownout.c index d90dcc911a..56609285cd 100644 --- a/components/esp_system/port/brownout.c +++ b/components/esp_system/port/brownout.c @@ -77,7 +77,7 @@ void esp_brownout_init(void) brownout_hal_config(&cfg); brownout_ll_intr_clear(); -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 // TODO: [ESP32C5] IDF-8647, [ESP32C61] IDF-9254 +#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61 // TODO: ESP32C61] IDF-9254 // TODO IDF-6606: LP_RTC_TIMER interrupt source is shared by lp_timer and brownout detector, but lp_timer interrupt // is not used now. An interrupt allocator is needed when lp_timer intr gets supported. esp_intr_alloc_intrstatus(ETS_LP_RTC_TIMER_INTR_SOURCE, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_SHARED, (uint32_t)brownout_ll_intr_get_status_reg(), BROWNOUT_DETECTOR_LL_INTERRUPT_MASK, &rtc_brownout_isr_handler, NULL, NULL); diff --git a/components/esp_system/port/soc/esp32c5/Kconfig.system b/components/esp_system/port/soc/esp32c5/Kconfig.system index 756610417d..50a039717d 100644 --- a/components/esp_system/port/soc/esp32c5/Kconfig.system +++ b/components/esp_system/port/soc/esp32c5/Kconfig.system @@ -13,7 +13,6 @@ menu "Brownout Detector" depends on ESP_BROWNOUT_DET default ESP_BROWNOUT_DET_LVL_SEL_7 help - TODO: [ESP32C5] IDF-8647 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 chip. diff --git a/components/hal/esp32c5/include/hal/brownout_ll.h b/components/hal/esp32c5/include/hal/brownout_ll.h new file mode 100644 index 0000000000..e103d2639c --- /dev/null +++ b/components/hal/esp32c5/include/hal/brownout_ll.h @@ -0,0 +1,148 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/readme.md + ******************************************************************************/ + +#pragma once +#include +#include "esp_bit_defs.h" +#include "soc/lp_analog_peri_struct.h" +#include "hal/regi2c_ctrl.h" +#include "hal/psdet_types.h" +#include "soc/regi2c_brownout.h" + +#define BROWNOUT_DETECTOR_LL_INTERRUPT_MASK (BIT(31)) +#define BROWNOUT_DETECTOR_LL_FIB_ENABLE (BIT(1)) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief suspend the flash when a brown out happens. + * + * @param enable true: suspend flash. false: not suspend + */ +static inline void brownout_ll_enable_flash_suspend(bool enable) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_close_flash_ena = enable; +} + +/** + * @brief power down the RF circuits when a brown out happens + * + * @param enable true: power down. false: not power down. + */ +static inline void brownout_ll_enable_rf_power_down(bool enable) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_pd_rf_ena = enable; +} + +/** + * @brief Configure the brown out detector to do a hardware reset + * + * @note: If brown out interrupt is also used, the hardware reset can be disabled, + * because we can call software reset in the interrupt handler. + * + * @param reset_ena true: enable reset. false: disable reset. + * @param reset_wait brown out reset wait cycles + * @param reset_level reset level + */ +static inline void brownout_ll_reset_config(bool reset_ena, uint32_t reset_wait, brownout_reset_level_t reset_level) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_reset_wait = reset_wait; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_reset_ena = reset_ena; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_reset_sel = reset_level; +} + +/** + * @brief Set brown out threshold voltage + * + * @param threshold brownout threshold + */ +static inline void brownout_ll_set_threshold(uint8_t threshold) +{ + REGI2C_WRITE_MASK(I2C_BOD, I2C_BOD_THRESHOLD, threshold); +} + +/** + * @brief Set this bit to enable the brown out detection + * + * @param bod_enable true: enable, false: disable + */ +static inline void brownout_ll_bod_enable(bool bod_enable) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_intr_ena = bod_enable; +} + +/** + * @brief configure the waiting cycles before sending an interrupt + * + * @param cycle waiting cycles. + */ +static inline void brownout_ll_set_intr_wait_cycles(uint8_t cycle) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_intr_wait = cycle; +} + +/** + * @brief Enable brown out interrupt + * + * @param enable true: enable, false: disable + */ +static inline void brownout_ll_intr_enable(bool enable) +{ + LP_ANA_PERI.int_ena.bod_mode0_int_ena = enable; +} + +/** + * @brief Enable brownout hardware reset (mode1) + * + * @param enable true: enable, false: disable + */ +static inline void brownout_ll_ana_reset_enable(bool enable) +{ + // give BOD mode1 control permission to the software + LP_ANA_PERI.fib_enable.val &= ~BROWNOUT_DETECTOR_LL_FIB_ENABLE; + // then we can enable or disable if we want the BOD mode1 to reset the system + LP_ANA_PERI.bod_mode1_cntl.bod_mode1_reset_ena = enable; +} + +/** + * @brief Clear interrupt bits. + */ +__attribute__((always_inline)) +static inline void brownout_ll_intr_clear(void) +{ + LP_ANA_PERI.int_clr.bod_mode0_int_clr = 1; +} + +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 1; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 0; +} + +/** + * @brief Get interrupt status register address + * + * @return Register address + */ +static inline volatile void *brownout_ll_intr_get_status_reg(void) +{ + return &LP_ANA_PERI.int_st; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index 9ff125a669..8585328da8 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -159,6 +159,10 @@ config SOC_IEEE802154_SUPPORTED bool default y +config SOC_BOD_SUPPORTED + bool + default y + config SOC_APM_SUPPORTED bool default y @@ -327,6 +331,10 @@ config SOC_ADC_SHARED_POWER bool default y +config SOC_BROWNOUT_RESET_SUPPORTED + bool + default y + config SOC_SHARED_IDCACHE_SUPPORTED bool default y diff --git a/components/soc/esp32c5/include/soc/regi2c_brownout.h b/components/soc/esp32c5/include/soc/regi2c_brownout.h new file mode 100644 index 0000000000..f9b43ebe98 --- /dev/null +++ b/components/soc/esp32c5/include/soc/regi2c_brownout.h @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +/** + * @file regi2c_brownout.h + * @brief Register definitions for brownout detector + * + * This file lists register fields of the brownout detector, located on an internal configuration + * bus. These definitions are used via macros defined in regi2c_ctrl.h. + */ + +#define I2C_BOD 0x61 +#define I2C_BOD_HOSTID 0 + +#define I2C_BOD_THRESHOLD 0x5 +#define I2C_BOD_THRESHOLD_MSB 2 +#define I2C_BOD_THRESHOLD_LSB 0 diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index a772b74cd8..9391698f6a 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -57,7 +57,7 @@ #define SOC_FLASH_ENC_SUPPORTED 1 #define SOC_SECURE_BOOT_SUPPORTED 1 #define SOC_IEEE802154_SUPPORTED 1 -// #define SOC_BOD_SUPPORTED 1 // TODO: [ESP32C5] IDF-8647 +#define SOC_BOD_SUPPORTED 1 #define SOC_APM_SUPPORTED 1 /*!< Support for APM peripheral */ #define SOC_PMU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8667 // #define SOC_PAU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 @@ -141,7 +141,7 @@ // #define SOC_APB_BACKUP_DMA (0) /*-------------------------- BROWNOUT CAPS -----------------------------------*/ -// #define SOC_BROWNOUT_RESET_SUPPORTED 1 +#define SOC_BROWNOUT_RESET_SUPPORTED 1 /*-------------------------- CACHE CAPS --------------------------------------*/ #define SOC_SHARED_IDCACHE_SUPPORTED 1 //Shared Cache for both instructions and data