diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 880478701..6a46abbf9 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -407,7 +407,6 @@ config TASK_WDT_CHECK_IDLE_TASK_CPU1 config BROWNOUT_DET bool "Hardware brownout detect & reset" default y - depends on NEEDS_ESP32_NEW_SILICON_REV help The ESP32 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 @@ -452,16 +451,6 @@ config BROWNOUT_DET_LVL default 7 if BROWNOUT_DET_LVL_SEL_7 -config BROWNOUT_DET_RESETDELAY - int "Brownout reset delay (in uS)" - depends on BROWNOUT_DET - range 0 6820 - default 1000 - help - The brownout detector can reset the chip after a certain delay, in order to make sure e.g. a voltage dip has entirely passed - before trying to restart the chip. You can set the delay here. - - choice ESP32_TIME_SYSCALL prompt "Timers used for gettimeofday function" default ESP32_TIME_SYSCALL_USE_RTC_FRC1 diff --git a/components/esp32/brownout.c b/components/esp32/brownout.c new file mode 100644 index 000000000..50d8ac044 --- /dev/null +++ b/components/esp32/brownout.c @@ -0,0 +1,61 @@ +// 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 +#include +#include +#include +#include "sdkconfig.h" +#include "soc/soc.h" +#include "soc/cpu.h" +#include "soc/rtc_cntl_reg.h" +#include "rom/ets_sys.h" +#include "esp_system.h" +#include "driver/rtc_cntl.h" +#include "freertos/FreeRTOS.h" + +#ifdef CONFIG_BROWNOUT_DET_LVL +#define BROWNOUT_DET_LVL CONFIG_BROWNOUT_DET_LVL +#else +#define BROWNOUT_DET_LVL 0 +#endif //CONFIG_BROWNOUT_DET_LVL + +static void rtc_brownout_isr_handler() +{ + /* 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() +{ + 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)); + + 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); +} diff --git a/components/soc/esp32/include/esp_brownout.h b/components/esp32/include/esp_brownout.h similarity index 100% rename from components/soc/esp32/include/esp_brownout.h rename to components/esp32/include/esp_brownout.h diff --git a/components/esp32/include/esp_system.h b/components/esp32/include/esp_system.h index 63592081f..f8ec1d3e0 100644 --- a/components/esp32/include/esp_system.h +++ b/components/esp32/include/esp_system.h @@ -59,6 +59,17 @@ void system_restore(void) __attribute__ ((deprecated)); */ void esp_restart(void) __attribute__ ((noreturn)); +/** + * @brief Internal function to restart PRO and APP CPUs. + * + * @note This function should not be called from FreeRTOS applications. + * Use esp_restart instead. + * + * This is an internal function called by esp_restart. It is called directly + * by the panic handler and brownout detector interrupt. + */ +void esp_restart_noos() __attribute__ ((noreturn)); + /** * @brief Restart system. * diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 0023a02eb..2f2826dcf 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -39,6 +39,7 @@ #include "esp_spi_flash.h" #include "esp_cache_err_int.h" #include "esp_app_trace.h" +#include "esp_system.h" #if CONFIG_SYSVIEW_ENABLE #include "SEGGER_RTT.h" #endif @@ -409,8 +410,6 @@ static void doBacktrace(XtExcFrame *frame) panicPutStr("\r\n\r\n"); } -void esp_restart_noos() __attribute__ ((noreturn)); - /* We arrive here after a panic or unhandled exception, when no OCD is detected. Dump the registers to the serial port and either jump to the gdb stub, halt the CPU or reboot. diff --git a/components/soc/esp32/brownout.c b/components/soc/esp32/brownout.c deleted file mode 100644 index 1dcde078e..000000000 --- a/components/soc/esp32/brownout.c +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2015-2016 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 -#include -#include -#include -#include "sdkconfig.h" -#include "soc/soc.h" -#include "soc/rtc_cntl_reg.h" - - -#if CONFIG_BROWNOUT_DET -/* -This file is included in esp-idf, but the menuconfig option for this is disabled because a silicon bug -prohibits the brownout detector from functioning correctly on the ESP32. -*/ - -void esp_brownout_init() { - WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, - RTC_CNTL_BROWN_OUT_ENA | (CONFIG_BROWNOUT_DET_LVL << RTC_CNTL_DBROWN_OUT_THRES_S) | - RTC_CNTL_BROWN_OUT_RST_ENA | (((CONFIG_BROWNOUT_DET_RESETDELAY*150)/1000) << RTC_CNTL_BROWN_OUT_RST_WAIT_S) | - RTC_CNTL_BROWN_OUT_PD_RF_ENA|RTC_CNTL_BROWN_OUT_CLOSE_FLASH_ENA); - -} - -#endif \ No newline at end of file