deep sleep: add API to control power down
This commit is contained in:
parent
88ddf5aefa
commit
35115885c5
6 changed files with 202 additions and 70 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
---------------------------------------------------------------*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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();
|
||||
}
|
Loading…
Reference in a new issue