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

deep sleep: add API to control power down

Ivan Grokhotkov 9 лет назад
Родитель
Сommit
35115885c5

+ 13 - 0
components/driver/include/driver/rtc_io.h

@@ -35,6 +35,7 @@ typedef struct {
     uint32_t pulldown;  /*!< Mask of pulldown enable */
     uint32_t slpsel;    /*!< Mask of the bit to select pin as wakeup pin */
     uint32_t slpie;     /*!< Mask of input enable in sleep mode */
+    uint32_t hold;      /*!< Mask of hold_force bit for RTC IO in RTC_CNTL_HOLD_FORCE_REG */
     int rtc_num;        /*!< RTC IO number, or -1 if not an RTC GPIO */
 } rtc_gpio_desc_t;
 
@@ -168,6 +169,18 @@ esp_err_t rtc_gpio_pullup_dis(gpio_num_t gpio_num);
  */
 esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num);
 
+/**
+ * @brief Disable "hold" signal for all RTC IOs
+ *
+ * Each RTC pad has a "hold" input signal from the RTC controller.
+ * If hold signal is set, pad latches current values of input enable,
+ * function, output enable, and other signals which come from the RTC mux.
+ * Hold signal is enabled before going into deep sleep for pins which
+ * are used for EXT1 wakeup.
+ */
+void rtc_gpio_unhold_all();
+
+
 #ifdef __cplusplus
 }
 #endif

+ 51 - 40
components/driver/rtc_module.c

@@ -40,46 +40,46 @@ portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED;
 
 //Reg,Mux,Fun,IE,Up,Down,Rtc_number
 const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = {
-    {RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_MUX_SEL_M, RTC_IO_TOUCH_PAD1_FUN_SEL_S, RTC_IO_TOUCH_PAD1_FUN_IE_M, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M, RTC_IO_TOUCH_PAD1_SLP_SEL_M, RTC_IO_TOUCH_PAD1_SLP_IE_M, 11}, //0
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //1
-    {RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_MUX_SEL_M, RTC_IO_TOUCH_PAD2_FUN_SEL_S, RTC_IO_TOUCH_PAD2_FUN_IE_M, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M, RTC_IO_TOUCH_PAD2_SLP_SEL_M, RTC_IO_TOUCH_PAD2_SLP_IE_M, 12}, //2
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //3
-    {RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_MUX_SEL_M, RTC_IO_TOUCH_PAD0_FUN_SEL_S, RTC_IO_TOUCH_PAD0_FUN_IE_M, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M, RTC_IO_TOUCH_PAD0_SLP_SEL_M, RTC_IO_TOUCH_PAD0_SLP_IE_M, 10}, //4
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //5
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //6
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //7
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //8
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //9
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //10
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //11
-    {RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_MUX_SEL_M, RTC_IO_TOUCH_PAD5_FUN_SEL_S, RTC_IO_TOUCH_PAD5_FUN_IE_M, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M, RTC_IO_TOUCH_PAD5_SLP_SEL_M, RTC_IO_TOUCH_PAD5_SLP_IE_M, 15}, //12
-    {RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_MUX_SEL_M, RTC_IO_TOUCH_PAD4_FUN_SEL_S, RTC_IO_TOUCH_PAD4_FUN_IE_M, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M, RTC_IO_TOUCH_PAD4_SLP_SEL_M, RTC_IO_TOUCH_PAD4_SLP_IE_M, 14}, //13
-    {RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_MUX_SEL_M, RTC_IO_TOUCH_PAD6_FUN_SEL_S, RTC_IO_TOUCH_PAD6_FUN_IE_M, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M, RTC_IO_TOUCH_PAD6_SLP_SEL_M, RTC_IO_TOUCH_PAD6_SLP_IE_M, 16}, //14
-    {RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_MUX_SEL_M, RTC_IO_TOUCH_PAD3_FUN_SEL_S, RTC_IO_TOUCH_PAD3_FUN_IE_M, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M, RTC_IO_TOUCH_PAD3_SLP_SEL_M, RTC_IO_TOUCH_PAD3_SLP_IE_M, 13}, //15
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //16
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //17
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //18
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //19
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //20
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //21
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //22
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //23
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //24
-    {RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_MUX_SEL_M, RTC_IO_PDAC1_FUN_SEL_S, RTC_IO_PDAC1_FUN_IE_M, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M, RTC_IO_PDAC1_SLP_SEL_M, RTC_IO_PDAC1_SLP_IE_M, 6},                           //25
-    {RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_MUX_SEL_M, RTC_IO_PDAC2_FUN_SEL_S, RTC_IO_PDAC2_FUN_IE_M, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M, RTC_IO_PDAC2_SLP_SEL_M, RTC_IO_PDAC2_SLP_IE_M, 7},                           //26
-    {RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_MUX_SEL_M, RTC_IO_TOUCH_PAD7_FUN_SEL_S, RTC_IO_TOUCH_PAD7_FUN_IE_M, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M, RTC_IO_TOUCH_PAD7_SLP_SEL_M, RTC_IO_TOUCH_PAD7_SLP_IE_M, 17}, //27
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //28
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //29
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //30
-    {0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //31
-    {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_MUX_SEL_M, RTC_IO_X32P_FUN_SEL_S, RTC_IO_X32P_FUN_IE_M, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M, RTC_IO_X32P_SLP_SEL_M, RTC_IO_X32P_SLP_IE_M, 9},                            //32
-    {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL_M, RTC_IO_X32N_FUN_SEL_S, RTC_IO_X32N_FUN_IE_M, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M, RTC_IO_X32N_SLP_SEL_M, RTC_IO_X32N_SLP_IE_M, 8},                            //33
-    {RTC_IO_ADC_PAD_REG, RTC_IO_ADC1_MUX_SEL_M, RTC_IO_ADC1_FUN_SEL_S, RTC_IO_ADC1_FUN_IE_M, 0, 0, RTC_IO_ADC1_SLP_SEL_M, RTC_IO_ADC1_SLP_IE_M, 4},                                                                //34
-    {RTC_IO_ADC_PAD_REG, RTC_IO_ADC2_MUX_SEL_M, RTC_IO_ADC2_FUN_SEL_S, RTC_IO_ADC2_FUN_IE_M, 0, 0, RTC_IO_ADC2_SLP_SEL_M, RTC_IO_ADC2_SLP_IE_M, 5},                                                                //35
-    {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE1_MUX_SEL_M, RTC_IO_SENSE1_FUN_SEL_S, RTC_IO_SENSE1_FUN_IE_M, 0, 0, RTC_IO_SENSE1_SLP_SEL_M, RTC_IO_SENSE1_SLP_IE_M, 0},                                                      //36
-    {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE2_MUX_SEL_M, RTC_IO_SENSE2_FUN_SEL_S, RTC_IO_SENSE2_FUN_IE_M, 0, 0, RTC_IO_SENSE2_SLP_SEL_M, RTC_IO_SENSE2_SLP_IE_M, 1},                                                      //37
-    {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE3_MUX_SEL_M, RTC_IO_SENSE3_FUN_SEL_S, RTC_IO_SENSE3_FUN_IE_M, 0, 0, RTC_IO_SENSE3_SLP_SEL_M, RTC_IO_SENSE3_SLP_IE_M, 2},                                                       //38
-    {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE4_MUX_SEL_M, RTC_IO_SENSE4_FUN_SEL_S, RTC_IO_SENSE4_FUN_IE_M, 0, 0, RTC_IO_SENSE4_SLP_SEL_M, RTC_IO_SENSE4_SLP_IE_M, 3},                                                      //39
+    {RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_MUX_SEL_M, RTC_IO_TOUCH_PAD1_FUN_SEL_S, RTC_IO_TOUCH_PAD1_FUN_IE_M, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M, RTC_IO_TOUCH_PAD1_SLP_SEL_M, RTC_IO_TOUCH_PAD1_SLP_IE_M, RTC_CNTL_TOUCH_PAD1_HOLD_FORCE_M, 11}, //0
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //1
+    {RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_MUX_SEL_M, RTC_IO_TOUCH_PAD2_FUN_SEL_S, RTC_IO_TOUCH_PAD2_FUN_IE_M, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M, RTC_IO_TOUCH_PAD2_SLP_SEL_M, RTC_IO_TOUCH_PAD2_SLP_IE_M, RTC_CNTL_TOUCH_PAD2_HOLD_FORCE_M, 12}, //2
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //3
+    {RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_MUX_SEL_M, RTC_IO_TOUCH_PAD0_FUN_SEL_S, RTC_IO_TOUCH_PAD0_FUN_IE_M, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M, RTC_IO_TOUCH_PAD0_SLP_SEL_M, RTC_IO_TOUCH_PAD0_SLP_IE_M, RTC_CNTL_TOUCH_PAD0_HOLD_FORCE_M, 10}, //4
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //5
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //6
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //7
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //8
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //9
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //10
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //11
+    {RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_MUX_SEL_M, RTC_IO_TOUCH_PAD5_FUN_SEL_S, RTC_IO_TOUCH_PAD5_FUN_IE_M, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M, RTC_IO_TOUCH_PAD5_SLP_SEL_M, RTC_IO_TOUCH_PAD5_SLP_IE_M, RTC_CNTL_TOUCH_PAD5_HOLD_FORCE_M, 15}, //12
+    {RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_MUX_SEL_M, RTC_IO_TOUCH_PAD4_FUN_SEL_S, RTC_IO_TOUCH_PAD4_FUN_IE_M, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M, RTC_IO_TOUCH_PAD4_SLP_SEL_M, RTC_IO_TOUCH_PAD4_SLP_IE_M, RTC_CNTL_TOUCH_PAD4_HOLD_FORCE_M, 14}, //13
+    {RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_MUX_SEL_M, RTC_IO_TOUCH_PAD6_FUN_SEL_S, RTC_IO_TOUCH_PAD6_FUN_IE_M, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M, RTC_IO_TOUCH_PAD6_SLP_SEL_M, RTC_IO_TOUCH_PAD6_SLP_IE_M, RTC_CNTL_TOUCH_PAD6_HOLD_FORCE_M, 16}, //14
+    {RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_MUX_SEL_M, RTC_IO_TOUCH_PAD3_FUN_SEL_S, RTC_IO_TOUCH_PAD3_FUN_IE_M, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M, RTC_IO_TOUCH_PAD3_SLP_SEL_M, RTC_IO_TOUCH_PAD3_SLP_IE_M, RTC_CNTL_TOUCH_PAD3_HOLD_FORCE_M, 13}, //15
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //16
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //17
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //18
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //19
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //20
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //21
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //22
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //23
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //24
+    {RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_MUX_SEL_M, RTC_IO_PDAC1_FUN_SEL_S, RTC_IO_PDAC1_FUN_IE_M, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M, RTC_IO_PDAC1_SLP_SEL_M, RTC_IO_PDAC1_SLP_IE_M, RTC_CNTL_PDAC1_HOLD_FORCE_M, 6},                           //25
+    {RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_MUX_SEL_M, RTC_IO_PDAC2_FUN_SEL_S, RTC_IO_PDAC2_FUN_IE_M, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M, RTC_IO_PDAC2_SLP_SEL_M, RTC_IO_PDAC2_SLP_IE_M, RTC_CNTL_PDAC1_HOLD_FORCE_M, 7},                           //26
+    {RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_MUX_SEL_M, RTC_IO_TOUCH_PAD7_FUN_SEL_S, RTC_IO_TOUCH_PAD7_FUN_IE_M, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M, RTC_IO_TOUCH_PAD7_SLP_SEL_M, RTC_IO_TOUCH_PAD7_SLP_IE_M, RTC_CNTL_TOUCH_PAD7_HOLD_FORCE_M, 17}, //27
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //28
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //29
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //30
+    {0, 0, 0, 0, 0, 0, 0, 0, 0, -1},                                                                                                                                            //31
+    {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_MUX_SEL_M, RTC_IO_X32P_FUN_SEL_S, RTC_IO_X32P_FUN_IE_M, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M, RTC_IO_X32P_SLP_SEL_M, RTC_IO_X32P_SLP_IE_M, RTC_CNTL_X32P_HOLD_FORCE_M, 9},                            //32
+    {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL_M, RTC_IO_X32N_FUN_SEL_S, RTC_IO_X32N_FUN_IE_M, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M, RTC_IO_X32N_SLP_SEL_M, RTC_IO_X32N_SLP_IE_M, RTC_CNTL_X32N_HOLD_FORCE_M, 8},                            //33
+    {RTC_IO_ADC_PAD_REG, RTC_IO_ADC1_MUX_SEL_M, RTC_IO_ADC1_FUN_SEL_S, RTC_IO_ADC1_FUN_IE_M, 0, 0, RTC_IO_ADC1_SLP_SEL_M, RTC_IO_ADC1_SLP_IE_M, RTC_CNTL_ADC1_HOLD_FORCE_M, 4},                                                                //34
+    {RTC_IO_ADC_PAD_REG, RTC_IO_ADC2_MUX_SEL_M, RTC_IO_ADC2_FUN_SEL_S, RTC_IO_ADC2_FUN_IE_M, 0, 0, RTC_IO_ADC2_SLP_SEL_M, RTC_IO_ADC2_SLP_IE_M, RTC_CNTL_ADC2_HOLD_FORCE_M, 5},                                                                //35
+    {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE1_MUX_SEL_M, RTC_IO_SENSE1_FUN_SEL_S, RTC_IO_SENSE1_FUN_IE_M, 0, 0, RTC_IO_SENSE1_SLP_SEL_M, RTC_IO_SENSE1_SLP_IE_M, RTC_CNTL_SENSE1_HOLD_FORCE_M, 0},                                                      //36
+    {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE2_MUX_SEL_M, RTC_IO_SENSE2_FUN_SEL_S, RTC_IO_SENSE2_FUN_IE_M, 0, 0, RTC_IO_SENSE2_SLP_SEL_M, RTC_IO_SENSE2_SLP_IE_M, RTC_CNTL_SENSE2_HOLD_FORCE_M, 1},                                                      //37
+    {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE3_MUX_SEL_M, RTC_IO_SENSE3_FUN_SEL_S, RTC_IO_SENSE3_FUN_IE_M, 0, 0, RTC_IO_SENSE3_SLP_SEL_M, RTC_IO_SENSE3_SLP_IE_M, RTC_CNTL_SENSE3_HOLD_FORCE_M, 2},                                                       //38
+    {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE4_MUX_SEL_M, RTC_IO_SENSE4_FUN_SEL_S, RTC_IO_SENSE4_FUN_IE_M, 0, 0, RTC_IO_SENSE4_SLP_SEL_M, RTC_IO_SENSE4_SLP_IE_M, RTC_CNTL_SENSE4_HOLD_FORCE_M, 3},                                                      //39
 };
 
 /*---------------------------------------------------------------
@@ -261,6 +261,17 @@ esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num)
     return ESP_OK;
 }
 
+void rtc_gpio_unhold_all()
+{
+    for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) {
+        const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio];
+        if (desc->hold != 0) {
+            REG_CLR_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold);
+        }
+    }
+}
+
+
 /*---------------------------------------------------------------
                     Touch Pad
 ---------------------------------------------------------------*/

+ 3 - 0
components/esp32/cpu_start.c

@@ -28,6 +28,8 @@
 #include "soc/rtc_cntl_reg.h"
 #include "soc/timer_group_reg.h"
 
+#include "driver/rtc_io.h"
+
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
 #include "freertos/semphr.h"
@@ -174,6 +176,7 @@ void start_cpu0_default(void)
 #if CONFIG_BROWNOUT_DET
     esp_brownout_init();
 #endif
+    rtc_gpio_unhold_all();
     esp_setup_time_syscalls();
     esp_vfs_dev_uart_register();
     esp_reent_init(_GLOBAL_REENT);

+ 81 - 4
components/esp32/deepsleep.c → components/esp32/deep_sleep.c

@@ -19,6 +19,7 @@
 #include "esp_log.h"
 #include "rom/cache.h"
 #include "rom/rtc.h"
+#include "rom/uart.h"
 #include "soc/cpu.h"
 #include "soc/rtc_cntl_reg.h"
 #include "soc/dport_reg.h"
@@ -35,6 +36,14 @@ static uint32_t s_wakeup_options = 0;
 static uint64_t s_sleep_duration = 0;
 
 static const char* TAG = "deepsleep";
+static esp_deep_sleep_pd_option_t s_pd_options[ESP_PD_DOMAIN_MAX] = {
+    ESP_PD_OPTION_AUTO,
+    ESP_PD_OPTION_AUTO,
+    ESP_PD_OPTION_AUTO,
+};
+
+static uint32_t get_power_down_flags();
+
 
 /* Wake from deep sleep stub
    See esp_deepsleep.h esp_wake_deep_sleep() comments for details.
@@ -85,6 +94,12 @@ void esp_deep_sleep(uint64_t time_in_us)
 
 void IRAM_ATTR esp_deep_sleep_start()
 {
+    uint32_t pd_flags = get_power_down_flags();
+
+    uart_tx_wait_idle(0);
+    uart_tx_wait_idle(1);
+    uart_tx_wait_idle(2);
+
     if (esp_get_deep_sleep_wake_stub() == NULL) {
         esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
     }
@@ -96,7 +111,7 @@ void IRAM_ATTR esp_deep_sleep_start()
         uint32_t period = rtc_slowck_cali(CALI_RTC_MUX, 128);
         rtc_usec2rtc(s_sleep_duration >> 32, s_sleep_duration & 0xffffffff, period, &cycle_h, &cycle_l);
     }
-    rtc_slp_prep_lite(DEEP_SLEEP_PD_NORMAL, 0);
+    rtc_slp_prep_lite(pd_flags, 0);
     rtc_sleep(cycle_h, cycle_l, s_wakeup_options, 0);
     while (1) {
         ;
@@ -108,7 +123,7 @@ void system_deep_sleep(uint64_t) __attribute__((alias("esp_deep_sleep")));
 esp_err_t esp_deep_sleep_enable_ulp_wakeup()
 {
 #ifdef CONFIG_ULP_COPROC_ENABLED
-    s_wakeup_options |= SAR_TRIG_EN;
+    s_wakeup_options |= RTC_SAR_TRIG_EN;
     return ESP_OK;
 #else
     return ESP_ERR_INVALID_STATE;
@@ -117,7 +132,7 @@ esp_err_t esp_deep_sleep_enable_ulp_wakeup()
 
 esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us)
 {
-    s_wakeup_options |= TIMER_EXPIRE_EN;
+    s_wakeup_options |= RTC_TIMER_EXPIRE_EN;
     s_sleep_duration = time_in_us;
     return ESP_OK;
 }
@@ -141,7 +156,7 @@ esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
 
 esp_err_t esp_deep_sleep_enable_ext1_wakeup(uint64_t mask, esp_ext1_wakeup_mode_t mode)
 {
-    if (mode > EXT1_WAKEUP_ANY_HIGH) {
+    if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) {
         return ESP_ERR_INVALID_ARG;
     }
     // Translate bit map of GPIO numbers into the bit map of RTC IO numbers
@@ -188,3 +203,65 @@ uint64_t esp_deep_sleep_get_ext1_wakeup_status()
     }
     return gpio_mask;
 }
+
+esp_err_t esp_deep_sleep_pd_config(esp_deep_sleep_pd_domain_t domain,
+                                   esp_deep_sleep_pd_option_t option)
+{
+    if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) {
+        return ESP_ERR_INVALID_ARG;
+    }
+    s_pd_options[domain] = option;
+    return ESP_OK;
+}
+
+static uint32_t get_power_down_flags()
+{
+    // Where needed, convert AUTO options to ON. Later interpret AUTO as OFF.
+
+    // RTC_SLOW_MEM is needed only for the ULP.
+    // If RTC_SLOW_MEM is Auto, and ULP wakeup isn't enabled, power down RTC_SLOW_MEM.
+    if (s_pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) {
+        if (s_wakeup_options & RTC_SAR_TRIG_EN) {
+            s_pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON;
+        }
+    }
+
+    // RTC_FAST_MEM is needed for deep sleep stub.
+    // If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub
+    // can run.
+    // In the new chip revision, deep sleep stub will be optional,
+    // and this can be changed.
+    if (s_pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] == ESP_PD_OPTION_AUTO) {
+        s_pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
+    }
+
+    // RTC_PERIPH is needed for EXT0 wakeup and for ULP.
+    // If RTC_PERIPH is auto, and both EXT0 and ULP aren't enabled,
+    // power down RTC_PERIPH.
+    if (s_pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) {
+        if (s_wakeup_options &
+                (RTC_SAR_TRIG_EN | RTC_EXT_EVENT0_TRIG_EN | RTC_EXT_EVENT1_TRIG_EN)) {
+            s_pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON;
+        }
+    }
+
+    const char* option_str[] = {"OFF", "ON", "OFF" /* Auto works as OFF */};
+    ESP_LOGD(TAG, "RTC_PERIPH: %s, RTC_SLOW_MEM: %s, RTC_FAST_MEM: %s",
+            option_str[s_pd_options[ESP_PD_DOMAIN_RTC_PERIPH]],
+            option_str[s_pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]],
+            option_str[s_pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]);
+
+    // Prepare flags based on the selected options
+    uint32_t pd_flags = DEEP_SLEEP_PD_NORMAL;
+    if (s_pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON) {
+        pd_flags |= DEEP_SLEEP_PD_RTC_FAST_MEM;
+    }
+    if (s_pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] != ESP_PD_OPTION_ON) {
+        pd_flags |= DEEP_SLEEP_PD_RTC_SLOW_MEM;
+    }
+    if (s_pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) {
+        pd_flags |= DEEP_SLEEP_PD_RTC_PERIPH;
+    }
+    ESP_LOGD(TAG, "power down flags: %02x", pd_flags);
+    return pd_flags;
+}

+ 52 - 24
components/esp32/include/esp_deep_sleep.h

@@ -34,34 +34,29 @@ extern "C" {
  * @brief Logic function used for EXT1 wakeup mode.
  */
 typedef enum {
-    EXT1_WAKEUP_ALL_LOW = 0,    //!< Wake the chip when all selected GPIOs go low
-    EXT1_WAKEUP_ANY_HIGH = 1    //!< Wake the chip when any of the selected GPIOs go high
+    ESP_EXT1_WAKEUP_ALL_LOW = 0,    //!< Wake the chip when all selected GPIOs go low
+    ESP_EXT1_WAKEUP_ANY_HIGH = 1    //!< Wake the chip when any of the selected GPIOs go high
 } esp_ext1_wakeup_mode_t;
 
 /**
- * @brief Parts of RTC power domain which can be powered down in deep sleep
+ * @brief Power domains which can be powered down in deep sleep
  */
 typedef enum {
-    RTC_POWER_DOMAIN_PERIPH,    //!< RTC IO, sensors and ULP co-processor
-    RTC_POWER_DOMAIN_SLOW_MEM,  //!< RTC slow memory
-    RTC_POWER_DOMAIN_FAST_MEM,  //!< RTC fast memory
-} esp_rtc_power_domain_t;
+    ESP_PD_DOMAIN_RTC_PERIPH,      //!< RTC IO, sensors and ULP co-processor
+    ESP_PD_DOMAIN_RTC_SLOW_MEM,    //!< RTC slow memory
+    ESP_PD_DOMAIN_RTC_FAST_MEM,    //!< RTC fast memory
+    ESP_PD_DOMAIN_MAX              //!< Number of domains
+} esp_deep_sleep_pd_domain_t;
 
 /**
- * @brief Enter deep-sleep mode
- *
- * The device will automatically wake up after the deep-sleep time
- * Upon waking up, the device calls deep sleep wake stub, and then proceeds
- * to load application.
- *
- * Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup
- * followed by a call to esp_deep_sleep_start.
- *
- * This function does not return.
- *
- * @param time_in_us  deep-sleep time, unit: microsecond
+ * @brief Power down options
  */
-void esp_deep_sleep(uint64_t time_in_us) __attribute__((noreturn));
+typedef enum {
+    ESP_PD_OPTION_OFF,      //!< Power down the power domain in deep sleep
+    ESP_PD_OPTION_ON,       //!< Keep power domain enabled during deep sleep
+    ESP_PD_OPTION_AUTO      //!< Keep power domain enabled in deep sleep, if it is needed by one of the wakeup options. Otherwise power it down.
+} esp_deep_sleep_pd_option_t;
+
 
 /**
  * @brief Enable wakeup by ULP coprocessor
@@ -104,6 +99,12 @@ esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
  * This function uses external wakeup feature of RTC controller.
  * It will work even if RTC peripherals are shut down during deep sleep.
  *
+ * @note Currently this doesn't actually work if RTC_PERIPH domain is
+ *       powered down. This is a known issue which will be resolved soon.
+ *       For now, unless esp_deep_sleep_pd_config function is used to
+ *       power down RTC_PERIPH domain, it will be kept on during deep sleep,
+ *       slightly increasing power consumption.
+ *
  * This feature can monitor any number of pins which are in RTC IOs.
  * Once any of the selected pins goes into the state given by level argument,
  * the chip will be woken up.
@@ -112,8 +113,8 @@ esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
  *              which are have RTC functionality can be used in this bit map:
  *              0,2,4,12-15,25-27,32-39.
  * @param mode select logic function used to determine wakeup condition:
- *            - EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low
- *            - EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high
+ *            - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low
+ *            - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high
  * @return
  *      - ESP_OK on success
  *      - ESP_ERR_INVALID_ARG if either of the arguments is out of range
@@ -130,8 +131,19 @@ esp_err_t esp_deep_sleep_enable_ext1_wakeup(uint64_t mask, esp_ext1_wakeup_mode_
  */
 uint64_t esp_deep_sleep_get_ext1_wakeup_status();
 
-
-void esp_deep_sleep_set_powerdown(esp_rtc_powerdown_t )
+/**
+ * @brief Set if specific power domain has to be powered down in deep sleep
+ *
+ * If not set set using this API, all power domains default to ESP_PD_OPTION_AUTO.
+ *
+ * @param domain  power domain to configure
+ * @param option  power down option (ESP_PD_OPTION_OFF, ESP_PD_OPTION_ON, or ESP_PD_OPTION_AUTO)
+ * @return
+ *      - ESP_OK on success
+ *      - ESP_ERR_INVALID_ARG if either of the arguments is out of range
+ */
+esp_err_t esp_deep_sleep_pd_config(esp_deep_sleep_pd_domain_t domain,
+                                   esp_deep_sleep_pd_option_t option);
 
 /**
  * @brief Enter deep sleep with the configured wakeup options
@@ -140,6 +152,22 @@ void esp_deep_sleep_set_powerdown(esp_rtc_powerdown_t )
  */
 void esp_deep_sleep_start() __attribute__((noreturn));
 
+/**
+ * @brief Enter deep-sleep mode
+ *
+ * The device will automatically wake up after the deep-sleep time
+ * Upon waking up, the device calls deep sleep wake stub, and then proceeds
+ * to load application.
+ *
+ * Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup
+ * followed by a call to esp_deep_sleep_start.
+ *
+ * This function does not return.
+ *
+ * @param time_in_us  deep-sleep time, unit: microsecond
+ */
+void esp_deep_sleep(uint64_t time_in_us) __attribute__((noreturn));
+
 /**
  * @brief Enter deep-sleep mode
  *

+ 2 - 2
components/esp32/test/test_deepsleep.c → components/esp32/test/test_deep_sleep.c

@@ -61,7 +61,7 @@ TEST_CASE("can wake up from deep sleep using ext1 (13 high)", "[deepsleep]")
     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
     ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
     ESP_ERROR_CHECK(gpio_pulldown_en(GPIO_NUM_13));
-    ESP_ERROR_CHECK(esp_deep_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), EXT1_WAKEUP_ANY_HIGH));
+    ESP_ERROR_CHECK(esp_deep_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH));
     esp_deep_sleep_start();
 }
 
@@ -70,6 +70,6 @@ TEST_CASE("can wake up from deep sleep using ext1 (13 low)", "[deepsleep]")
     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
     ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
     ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
-    ESP_ERROR_CHECK(esp_deep_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), EXT1_WAKEUP_ALL_LOW));
+    ESP_ERROR_CHECK(esp_deep_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
     esp_deep_sleep_start();
 }