diff --git a/components/esp32/brownout.c b/components/esp32/brownout.c index c3db402717..4dbfc83456 100644 --- a/components/esp32/brownout.c +++ b/components/esp32/brownout.c @@ -20,6 +20,7 @@ #include "soc/soc.h" #include "soc/cpu.h" #include "soc/rtc_periph.h" +#include "hal/brownout_hal.h" #include "esp32/rom/ets_sys.h" #include "esp_private/system_internal.h" #include "driver/rtc_cntl.h" @@ -49,14 +50,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 = false, + .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); } diff --git a/components/esp32s2/Kconfig b/components/esp32s2/Kconfig index ea4fb2f0e1..ccbe51872c 100644 --- a/components/esp32s2/Kconfig +++ b/components/esp32s2/Kconfig @@ -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 diff --git a/components/esp32s2/brownout.c b/components/esp32s2/brownout.c index 986ed73077..e4eef7cb17 100644 --- a/components/esp32s2/brownout.c +++ b/components/esp32s2/brownout.c @@ -17,10 +17,11 @@ #include #include #include "sdkconfig.h" +#include "esp_log.h" #include "soc/soc.h" #include "soc/cpu.h" -#include "soc/rtc_cntl_reg.h" -#include "esp32s2/rom/ets_sys.h" +#include "soc/rtc_periph.h" +#include "hal/brownout_hal.h" #include "esp_private/system_internal.h" #include "driver/rtc_cntl.h" #include "freertos/FreeRTOS.h" @@ -42,15 +43,24 @@ static void rtc_brownout_isr_handler(void *arg) * at the same time as the following ets_printf. */ esp_cpu_stall(!xPortGetCoreID()); + esp_reset_reason_set_hint(ESP_RST_BROWNOUT); 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 + brownout_hal_config_t cfg = { + .threshold = BROWNOUT_DET_LVL, + .enabled = true, + .reset_enabled = false, + .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); } diff --git a/components/soc/esp32/brownout_hal.c b/components/soc/esp32/brownout_hal.c new file mode 100644 index 0000000000..5fc448601b --- /dev/null +++ b/components/soc/esp32/brownout_hal.c @@ -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; +} diff --git a/components/soc/esp32/include/soc/brownout_caps.h b/components/soc/esp32/include/soc/brownout_caps.h new file mode 100644 index 0000000000..5e867a8926 --- /dev/null +++ b/components/soc/esp32/include/soc/brownout_caps.h @@ -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 diff --git a/components/soc/esp32/sources.cmake b/components/soc/esp32/sources.cmake index d32f5d9251..01a0fc69af 100644 --- a/components/soc/esp32/sources.cmake +++ b/components/soc/esp32/sources.cmake @@ -1,4 +1,5 @@ set(SOC_SRCS "adc_periph.c" + "brownout_hal.c" "dac_periph.c" "cpu_util.c" "gpio_periph.c" diff --git a/components/soc/esp32s2/brownout_hal.c b/components/soc/esp32s2/brownout_hal.c new file mode 100644 index 0000000000..74e60e9ede --- /dev/null +++ b/components/soc/esp32s2/brownout_hal.c @@ -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; +} diff --git a/components/soc/esp32s2/i2c_brownout.h b/components/soc/esp32s2/i2c_brownout.h new file mode 100644 index 0000000000..5fac2c91b3 --- /dev/null +++ b/components/soc/esp32s2/i2c_brownout.h @@ -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 diff --git a/components/soc/esp32s2/include/soc/brownout_caps.h b/components/soc/esp32s2/include/soc/brownout_caps.h new file mode 100644 index 0000000000..797d33ebb9 --- /dev/null +++ b/components/soc/esp32s2/include/soc/brownout_caps.h @@ -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 diff --git a/components/soc/esp32s2/sources.cmake b/components/soc/esp32s2/sources.cmake index 4293a18b0a..5a8711bb8b 100644 --- a/components/soc/esp32s2/sources.cmake +++ b/components/soc/esp32s2/sources.cmake @@ -1,4 +1,5 @@ set(SOC_SRCS "adc_periph.c" + "brownout_hal.c" "dac_periph.c" "cpu_util.c" "gpio_periph.c" diff --git a/components/soc/include/hal/brownout_hal.h b/components/soc/include/hal/brownout_hal.h new file mode 100644 index 0000000000..ac65506ed2 --- /dev/null +++ b/components/soc/include/hal/brownout_hal.h @@ -0,0 +1,47 @@ +// 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 +#include +#include + +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