• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <stdint.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdbool.h>
19 
20 #include "esp_private/system_internal.h"
21 #include "driver/rtc_cntl.h"
22 
23 #include "esp_rom_sys.h"
24 
25 #include "soc/soc.h"
26 #include "soc/cpu.h"
27 #include "soc/rtc_periph.h"
28 #include "hal/cpu_hal.h"
29 
30 #include "hal/brownout_hal.h"
31 
32 #include "sdkconfig.h"
33 
34 #if defined(CONFIG_ESP32_BROWNOUT_DET_LVL)
35 #define BROWNOUT_DET_LVL CONFIG_ESP32_BROWNOUT_DET_LVL
36 #elif defined(CONFIG_ESP32S2_BROWNOUT_DET_LVL)
37 #define BROWNOUT_DET_LVL CONFIG_ESP32S2_BROWNOUT_DET_LVL
38 #elif defined(CONFIG_ESP32S3_BROWNOUT_DET_LVL)
39 #define BROWNOUT_DET_LVL CONFIG_ESP32S3_BROWNOUT_DET_LVL
40 #elif defined(CONFIG_ESP32C3_BROWNOUT_DET_LVL)
41 #define BROWNOUT_DET_LVL CONFIG_ESP32C3_BROWNOUT_DET_LVL
42 #else
43 #define BROWNOUT_DET_LVL 0
44 #endif
45 
46 #if SOC_BROWNOUT_RESET_SUPPORTED
47 #define BROWNOUT_RESET_EN true
48 #else
49 #define BROWNOUT_RESET_EN false
50 #endif // SOC_BROWNOUT_RESET_SUPPORTED
51 
52 #ifndef SOC_BROWNOUT_RESET_SUPPORTED
rtc_brownout_isr_handler(void * arg)53 static void rtc_brownout_isr_handler(void *arg)
54 {
55     /* Normally RTC ISR clears the interrupt flag after the application-supplied
56      * handler returns. Since restart is called here, the flag needs to be
57      * cleared manually.
58      */
59     brownout_hal_intr_clear();
60     /* Stall the other CPU to make sure the code running there doesn't use UART
61      * at the same time as the following esp_rom_printf.
62      */
63     esp_cpu_stall(!cpu_hal_get_core_id());
64     esp_reset_reason_set_hint(ESP_RST_BROWNOUT);
65     esp_rom_printf("\r\nBrownout detector was triggered\r\n\r\n");
66     esp_restart_noos();
67 }
68 #endif // not SOC_BROWNOUT_RESET_SUPPORTED
69 
esp_brownout_init(void)70 void esp_brownout_init(void)
71 {
72     brownout_hal_config_t cfg = {
73         .threshold = BROWNOUT_DET_LVL,
74         .enabled = true,
75         .reset_enabled = BROWNOUT_RESET_EN,
76         .flash_power_down = true,
77         .rf_power_down = true,
78     };
79 
80     brownout_hal_config(&cfg);
81 
82 
83 #ifndef SOC_BROWNOUT_RESET_SUPPORTED
84     rtc_isr_register(rtc_brownout_isr_handler, NULL, RTC_CNTL_BROWN_OUT_INT_ENA_M);
85 
86     brownout_hal_intr_enable(true);
87 #endif // not SOC_BROWNOUT_RESET_SUPPORTED
88 }
89 
esp_brownout_disable(void)90 void esp_brownout_disable(void)
91 {
92     brownout_hal_config_t cfg = {
93         .enabled = false,
94     };
95 
96     brownout_hal_config(&cfg);
97 
98 #ifndef SOC_BROWNOUT_RESET_SUPPORTED
99     brownout_hal_intr_enable(false);
100 
101     rtc_isr_deregister(rtc_brownout_isr_handler, NULL);
102 #endif // not SOC_BROWNOUT_RESET_SUPPORTED
103 }
104