Просмотр исходного кода

Merge branch 'feature/esp32s2_brownout' into 'master'

esp32s2: add brownout detector support

Closes IDF-751

See merge request espressif/esp-idf!7428
Ivan Grokhotkov 6 лет назад
Родитель
Сommit
41631587f8

+ 0 - 1
components/esp32/CMakeLists.txt

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

+ 1 - 2
components/esp32s2/CMakeLists.txt

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

+ 16 - 19
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

+ 0 - 56
components/esp32s2/brownout.c

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

+ 2 - 1
components/esp_common/CMakeLists.txt

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

+ 24 - 11
components/esp32/brownout.c → components/esp_common/src/brownout.c

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

+ 41 - 0
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;
+}

+ 27 - 0
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

+ 1 - 0
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"

+ 46 - 0
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;
+}

+ 30 - 0
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

+ 1 - 22
components/soc/esp32s2/include/hal/adc_ll.h

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

+ 25 - 0
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

+ 5 - 10
components/soc/esp32s2/include/soc/rtc_cntl_struct.h

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

+ 1 - 0
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"

+ 48 - 0
components/soc/include/hal/brownout_hal.h

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