feat(brownout): Add brownout detector support on esp32c5

This commit is contained in:
C.S.M 2024-08-19 15:49:08 +08:00
parent fab065848d
commit e76c2c4b53
7 changed files with 184 additions and 7 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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.

View File

@ -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 <stdbool.h>
#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

View File

@ -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

View File

@ -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

View File

@ -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