Merge branch 'feature/esp32s2_brownout' into 'master'

esp32s2: add brownout detector support

Closes IDF-751

See merge request espressif/esp-idf!7428
This commit is contained in:
Ivan Grokhotkov 2020-02-04 17:00:46 +08:00
commit 41631587f8
16 changed files with 268 additions and 122 deletions

View File

@ -12,7 +12,6 @@ if(BOOTLOADER_BUILD)
else()
# Regular app build
set(srcs
"brownout.c"
"cache_err_int.c"
"cache_sram_mmu.c"
"clk.c"

View File

@ -11,8 +11,7 @@ if(BOOTLOADER_BUILD)
else()
# Regular app build
set(srcs "brownout.c"
"cache_err_int.c"
set(srcs "cache_err_int.c"
"clk.c"
"cpu_start.c"
"crosscore_int.c"

View File

@ -364,42 +364,39 @@ menu "ESP32S2-specific"
bool "Hardware brownout detect & reset"
default y
help
The ESP32S2 has a built-in brownout detector which can detect if the voltage is lower than
The ESP32-S2 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
behaviour.
choice ESP32S2_BROWNOUT_DET_LVL_SEL
prompt "Brownout voltage level"
depends on ESP32S2_BROWNOUT_DET
default ESP32S2_BROWNOUT_DET_LVL_SEL_0
default ESP32S2_BROWNOUT_DET_LVL_SEL_7
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 ESP32 chip.
between each ESP3-S2 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 ESP32S2_BROWNOUT_DET_LVL_SEL_0
bool "2.43V +/- 0.05"
config ESP32S2_BROWNOUT_DET_LVL_SEL_1
bool "2.48V +/- 0.05"
config ESP32S2_BROWNOUT_DET_LVL_SEL_2
bool "2.58V +/- 0.05"
config ESP32S2_BROWNOUT_DET_LVL_SEL_3
bool "2.62V +/- 0.05"
config ESP32S2_BROWNOUT_DET_LVL_SEL_4
bool "2.67V +/- 0.05"
config ESP32S2_BROWNOUT_DET_LVL_SEL_5
bool "2.70V +/- 0.05"
config ESP32S2_BROWNOUT_DET_LVL_SEL_6
bool "2.77V +/- 0.05"
config ESP32S2_BROWNOUT_DET_LVL_SEL_7
bool "2.80V +/- 0.05"
bool "2.44V"
config ESP32S2_BROWNOUT_DET_LVL_SEL_6
bool "2.56V"
config ESP32S2_BROWNOUT_DET_LVL_SEL_5
bool "2.67V"
config ESP32S2_BROWNOUT_DET_LVL_SEL_4
bool "2.84V"
config ESP32S2_BROWNOUT_DET_LVL_SEL_3
bool "2.98V"
config ESP32S2_BROWNOUT_DET_LVL_SEL_2
bool "3.19V"
config ESP32S2_BROWNOUT_DET_LVL_SEL_1
bool "3.30V"
endchoice
config ESP32S2_BROWNOUT_DET_LVL
int
default 0 if ESP32S2_BROWNOUT_DET_LVL_SEL_0
default 1 if ESP32S2_BROWNOUT_DET_LVL_SEL_1
default 2 if ESP32S2_BROWNOUT_DET_LVL_SEL_2
default 3 if ESP32S2_BROWNOUT_DET_LVL_SEL_3

View File

@ -1,56 +0,0 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "sdkconfig.h"
#include "soc/soc.h"
#include "soc/cpu.h"
#include "soc/rtc_cntl_reg.h"
#include "esp32s2/rom/ets_sys.h"
#include "esp_private/system_internal.h"
#include "driver/rtc_cntl.h"
#include "freertos/FreeRTOS.h"
#ifdef CONFIG_ESP32S2_BROWNOUT_DET_LVL
#define BROWNOUT_DET_LVL CONFIG_ESP32S2_BROWNOUT_DET_LVL
#else
#define BROWNOUT_DET_LVL 0
#endif //CONFIG_ESP32S2_BROWNOUT_DET_LVL
static void rtc_brownout_isr_handler(void *arg)
{
/* Normally RTC ISR clears the interrupt flag after the application-supplied
* handler returns. Since restart is called here, the flag needs to be
* cleared manually.
*/
REG_WRITE(RTC_CNTL_INT_CLR_REG, RTC_CNTL_BROWN_OUT_INT_CLR);
/* Stall the other CPU to make sure the code running there doesn't use UART
* at the same time as the following ets_printf.
*/
esp_cpu_stall(!xPortGetCoreID());
ets_printf("\r\nBrownout detector was triggered\r\n\r\n");
esp_restart_noos();
}
void esp_brownout_init(void)
{
// TODO: implement brownout threshold configuration for esp32s2 - IDF-751
ESP_ERROR_CHECK( rtc_isr_register(rtc_brownout_isr_handler, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M) );
REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_BROWN_OUT_INT_ENA_M);
}

View File

@ -6,7 +6,8 @@ if(BOOTLOADER_BUILD)
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-Wl,--gc-sections")
else()
# Regular app build
set(srcs "src/dbg_stubs.c"
set(srcs "src/brownout.c"
"src/dbg_stubs.c"
"src/esp_err_to_name.c"
"src/esp_timer.c"
"src/ets_timer_legacy.c"

View File

@ -17,19 +17,29 @@
#include <stdlib.h>
#include <stdbool.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "soc/soc.h"
#include "soc/cpu.h"
#include "soc/rtc_periph.h"
#include "esp32/rom/ets_sys.h"
#include "hal/brownout_hal.h"
#include "esp_private/system_internal.h"
#include "driver/rtc_cntl.h"
#include "freertos/FreeRTOS.h"
#ifdef CONFIG_ESP32_BROWNOUT_DET_LVL
#if defined(CONFIG_ESP32_BROWNOUT_DET_LVL)
#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
#else
#define BROWNOUT_DET_LVL 0
#endif //CONFIG_ESP32_BROWNOUT_DET_LVL
#endif
#ifdef SOC_BROWNOUT_RESET_SUPPORTED
#define BROWNOUT_RESET_EN true
#else
#define BROWNOUT_RESET_EN false
#endif // SOC_BROWNOUT_RESET_SUPPORTED
static void rtc_brownout_isr_handler(void *arg)
{
@ -37,7 +47,7 @@ static void rtc_brownout_isr_handler(void *arg)
* handler returns. Since restart is called here, the flag needs to be
* cleared manually.
*/
REG_WRITE(RTC_CNTL_INT_CLR_REG, RTC_CNTL_BROWN_OUT_INT_CLR);
brownout_hal_intr_clear();
/* Stall the other CPU to make sure the code running there doesn't use UART
* at the same time as the following ets_printf.
*/
@ -49,14 +59,17 @@ static void rtc_brownout_isr_handler(void *arg)
void esp_brownout_init(void)
{
REG_WRITE(RTC_CNTL_BROWN_OUT_REG,
RTC_CNTL_BROWN_OUT_ENA /* Enable BOD */
| RTC_CNTL_BROWN_OUT_PD_RF_ENA /* Automatically power down RF */
/* Reset timeout must be set to >1 even if BOR feature is not used */
| (2 << RTC_CNTL_BROWN_OUT_RST_WAIT_S)
| (BROWNOUT_DET_LVL << RTC_CNTL_DBROWN_OUT_THRES_S));
brownout_hal_config_t cfg = {
.threshold = BROWNOUT_DET_LVL,
.enabled = true,
.reset_enabled = BROWNOUT_RESET_EN,
.flash_power_down = true,
.rf_power_down = true,
};
brownout_hal_config(&cfg);
ESP_ERROR_CHECK( rtc_isr_register(rtc_brownout_isr_handler, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M) );
REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_BROWN_OUT_INT_ENA_M);
brownout_hal_intr_enable(true);
}

View File

@ -0,0 +1,41 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "hal/brownout_hal.h"
#include "soc/rtc_cntl_struct.h"
void brownout_hal_config(const brownout_hal_config_t *cfg)
{
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,
.thres = cfg->threshold,
.ena = cfg->enabled,
};
RTCCNTL.brown_out = brown_out_reg;
}
void brownout_hal_intr_enable(bool enable)
{
RTCCNTL.int_ena.rtc_brown_out = enable;
}
void brownout_hal_intr_clear(void)
{
RTCCNTL.int_clr.rtc_brown_out = 1;
}

View File

@ -0,0 +1,27 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#if (CONFIG_ESP32_REV_MIN >= 1)
#define SOC_BROWNOUT_RESET_SUPPORTED 1
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,4 +1,5 @@
set(SOC_SRCS "adc_periph.c"
"brownout_hal.c"
"dac_periph.c"
"cpu_util.c"
"gpio_periph.c"

View File

@ -0,0 +1,46 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "hal/brownout_hal.h"
#include "soc/rtc_cntl_struct.h"
#include "soc/rtc_cntl_reg.h"
#include "i2c_rtc_clk.h"
#include "i2c_brownout.h"
void brownout_hal_config(const brownout_hal_config_t *cfg)
{
I2C_WRITEREG_MASK_RTC(I2C_BOD, I2C_BOD_THRESHOLD, cfg->threshold);
typeof(RTCCNTL.brown_out) brown_out_reg = {
.out2_ena = 1,
.int_wait = 0x002,
.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,
};
RTCCNTL.brown_out = brown_out_reg;
}
void brownout_hal_intr_enable(bool enable)
{
RTCCNTL.int_ena.rtc_brown_out = enable;
}
void brownout_hal_intr_clear(void)
{
RTCCNTL.int_clr.rtc_brown_out = 1;
}

View File

@ -0,0 +1,30 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
/**
* @file i2c_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 i2c_rtc_clk.h.
*/
#define I2C_BOD 0x61
#define I2C_BOD_HOSTID 1
#define I2C_BOD_THRESHOLD 0x5
#define I2C_BOD_THRESHOLD_MSB 2
#define I2C_BOD_THRESHOLD_LSB 0

View File

@ -586,26 +586,5 @@ static inline void adc_ll_set_hall_controller(adc_ll_hall_controller_t hall_ctrl
*/
static inline bool adc_ll_vref_output(int io)
{
int channel;
if (io == 25) {
channel = 8; //Channel 8 bit
} else if (io == 26) {
channel = 9; //Channel 9 bit
} else if (io == 27) {
channel = 7; //Channel 7 bit
} else {
return false;
}
RTCCNTL.bias_conf.dbg_atten = 0; //Check DBG effect outside sleep mode
//set dtest (MUX_SEL : 0 -> RTC; 1-> vdd_sar2)
RTCCNTL.test_mux.dtest_rtc = 1; //Config test mux to route v_ref to ADC2 Channels
//set ent
RTCCNTL.test_mux.ent_rtc = 1;
//set sar2_en_test
SENS.sar_meas2_ctrl1.sar2_en_test = 1;
//set sar2 en force
SENS.sar_meas2_ctrl2.sar2_en_pad_force = 1; //Pad bitmap controlled by SW
//set en_pad for channels 7,8,9 (bits 0x380)
SENS.sar_meas2_ctrl2.sar2_en_pad = 1 << channel;
return true;
return false;
}

View File

@ -0,0 +1,25 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define SOC_BROWNOUT_RESET_SUPPORTED 1
#ifdef __cplusplus
}
#endif

View File

@ -13,6 +13,9 @@
// limitations under the License.
#ifndef _SOC_RTC_CNTL_STRUCT_H_
#define _SOC_RTC_CNTL_STRUCT_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -554,15 +557,6 @@ typedef volatile struct {
uint32_t val;
} swd_conf;
uint32_t swd_wprotect; /*swd write protect*/
union {
struct {
uint32_t reserved0: 28;
uint32_t ent_tsens: 1; /*ENT_TSENS*/
uint32_t ent_rtc: 1; /*ENT_RTC*/
uint32_t dtest_rtc: 2;
};
uint32_t val;
} test_mux;
union {
struct {
uint32_t reserved0: 20;
@ -656,7 +650,8 @@ typedef volatile struct {
} ext_wakeup1_status;
union {
struct {
uint32_t reserved0: 4;
uint32_t out2_ena: 1; /*enable brown_out2 to start chip reset*/
uint32_t reserved1: 3;
uint32_t int_wait: 10; /*brown out interrupt wait cycles*/
uint32_t close_flash_ena: 1; /*enable close flash when brown out happens*/
uint32_t pd_rf_ena: 1; /*enable power down RF when brown out happens*/

View File

@ -1,4 +1,5 @@
set(SOC_SRCS "adc_periph.c"
"brownout_hal.c"
"dac_periph.c"
"cpu_util.c"
"gpio_periph.c"

View File

@ -0,0 +1,48 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
* NOTICE
* The hal is not public api, don't use in application code.
* See readme.md in soc/include/hal/readme.md
******************************************************************************/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "soc/brownout_caps.h"
typedef struct {
uint8_t threshold;
bool enabled;
bool reset_enabled;
bool flash_power_down;
bool rf_power_down;
} brownout_hal_config_t;
void brownout_hal_config(const brownout_hal_config_t *cfg);
void brownout_hal_intr_enable(bool enable);
void brownout_hal_intr_clear(void);
#ifdef __cplusplus
}
#endif