//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, 11}, //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, 12}, //2
- {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, 10}, //4
- {0, 0, 0, 0, 0, 0, -1}, //5
- {0, 0, 0, 0, 0, 0, -1}, //6
- {0, 0, 0, 0, 0, 0, -1}, //7
- {0, 0, 0, 0, 0, 0, -1}, //8
- {0, 0, 0, 0, 0, 0, -1}, //9
- {0, 0, 0, 0, 0, 0, -1}, //10
- {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, 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, 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, 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, 13}, //15
- {0, 0, 0, 0, 0, 0, -1}, //16
- {0, 0, 0, 0, 0, 0, -1}, //17
- {0, 0, 0, 0, 0, 0, -1}, //18
- {0, 0, 0, 0, 0, 0, -1}, //19
- {0, 0, 0, 0, 0, 0, -1}, //20
- {0, 0, 0, 0, 0, 0, -1}, //21
- {0, 0, 0, 0, 0, 0, -1}, //22
- {0, 0, 0, 0, 0, 0, -1}, //23
- {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, 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, 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, 17}, //27
- {0, 0, 0, 0, 0, 0, -1}, //28
- {0, 0, 0, 0, 0, 0, -1}, //29
- {0, 0, 0, 0, 0, 0, -1}, //30
- {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, 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, 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, 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, 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, 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, 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, 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, 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, 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
};
/*---------------------------------------------------------------
-/* Wake from deep sleep stub
+// 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.
- See esp_deepsleep.h esp_wake_deep_sleep() comments for details.
-*/
#include <stddef.h>
#include <sys/lock.h>
#include "rom/cache.h"
#include "soc/dport_reg.h"
#include "esp_attr.h"
#include "esp_deepsleep.h"
+#include "esp_log.h"
+#include "soc/cpu.h"
#include "rtc.h"
+#include "driver/rtc_io.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
/* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc()
is not thread-safe. */
static _lock_t lock_rtc_memory_crc;
+static uint32_t s_wakeup_options = 0;
+static uint64_t s_sleep_duration = 0;
+static const char* TAG = "deepsleep";
+
+/* Wake from deep sleep stub
+ See esp_deepsleep.h esp_wake_deep_sleep() comments for details.
+*/
esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void)
{
_lock_acquire(&lock_rtc_memory_crc);
void esp_deep_sleep(uint64_t time_in_us)
{
- rtc_set_cpu_freq(CPU_XTAL);
+ esp_deep_sleep_enable_timer_wakeup(time_in_us);
+ esp_deep_sleep_start();
+}
+
+void IRAM_ATTR esp_deep_sleep_start()
+{
if (esp_get_deep_sleep_wake_stub() == NULL) {
esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
}
- uint32_t period = rtc_slowck_cali(CALI_RTC_MUX, 128);
- uint32_t cycle_l, cycle_h;
- rtc_usec2rtc(time_in_us >> 32, time_in_us, period, &cycle_h, &cycle_l);
- rtc_slp_prep_lite(1, 0);
- rtc_sleep(cycle_h, cycle_l, TIMER_EXPIRE_EN, 0);
+
+ rtc_set_cpu_freq(CPU_XTAL);
+ uint32_t cycle_h = 0;
+ uint32_t cycle_l = 0;
+ if (s_sleep_duration > 0) {
+ 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_sleep(cycle_h, cycle_l, s_wakeup_options, 0);
while (1) {
;
}
}
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;
+ return ESP_OK;
+#else
+ return ESP_ERR_INVALID_STATE;
+#endif
+}
+
+esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us)
+{
+ s_wakeup_options |= TIMER_EXPIRE_EN;
+ s_sleep_duration = time_in_us;
+ return ESP_OK;
+}
+
+esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
+{
+ if (level < 0 || level > 1) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ if (!RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio_num];
+ REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, desc->rtc_num);
+ SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, level, RTC_CNTL_EXT_WAKEUP0_LV_S);
+ REG_SET_BIT(desc->reg, desc->slpsel);
+ REG_SET_BIT(desc->reg, desc->slpie);
+ s_wakeup_options |= RTC_EXT_EVENT0_TRIG_EN;
+ return ESP_OK;
+}
+
+esp_err_t esp_deep_sleep_enable_ext1_wakeup(uint64_t mask, esp_ext1_wakeup_mode_t mode)
+{
+ if (mode > EXT1_WAKEUP_ANY_HIGH) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ // Translate bit map of GPIO numbers into the bit map of RTC IO numbers
+ uint32_t rtc_gpio_mask = 0;
+ for (int gpio = 0; mask; ++gpio, mask >>= 1) {
+ if ((mask & 1) == 0) {
+ continue;
+ }
+ if (!RTC_GPIO_IS_VALID_GPIO(gpio)) {
+ ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio);
+ return ESP_ERR_INVALID_ARG;
+ }
+ const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio];
+ int rtc_pin = desc->rtc_num;
+ rtc_gpio_mask |= BIT(rtc_pin);
+ REG_SET_BIT(desc->reg, desc->slpsel);
+ REG_SET_BIT(desc->reg, desc->slpie);
+ }
+ REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR);
+ REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, rtc_gpio_mask);
+ SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, mode, RTC_CNTL_EXT_WAKEUP1_LV_S);
+ s_wakeup_options |= RTC_EXT_EVENT1_TRIG_EN;
+ return ESP_OK;
+}
+
+uint64_t esp_deep_sleep_get_ext1_wakeup_status()
+{
+ int wakeup_reason = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE);
+ if (wakeup_reason != RTC_EXT_EVENT1_TRIG) {
+ return 0;
+ }
+ uint32_t status = REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS);
+ // Translate bit map of RTC IO numbers into the bit map of GPIO numbers
+ uint64_t gpio_mask = 0;
+ for (int gpio = 0; gpio < 40; ++gpio) {
+ if (!RTC_GPIO_IS_VALID_GPIO(gpio)) {
+ continue;
+ }
+ int rtc_pin = rtc_gpio_desc[gpio].rtc_num;
+ if ((status & BIT(rtc_pin)) == 0) {
+ continue;
+ }
+ gpio_mask |= BIT(gpio);
+ }
+ return gpio_mask;
+}
// 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
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef __ESP_DEEPSLEEP_H__
-#define __ESP_DEEPSLEEP_H_
+#pragma once
#include <stdint.h>
+#include "esp_err.h"
+#include "driver/gpio.h"
#ifdef __cplusplus
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_mode_t;
+
/**
* @brief Enter deep-sleep mode
*
* 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 Enable wakeup by ULP coprocessor
+ * @return
+ * - ESP_OK on success
+ * - ESP_ERR_INVALID_STATE if ULP co-processor is not enabled.
+ */
+esp_err_t esp_deep_sleep_enable_ulp_wakeup();
+
+/**
+ * @brief Enable wakeup by timer
+ * @param time_in_us time before wakeup, in microseconds
+ * @return
+ * - ESP_OK on success
+ * - ESP_ERR_INVALID_ARG if value is out of range (TBD)
+ */
+esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us);
+
+/**
+ * @brief Enable wakeup using a pin
+ *
+ * This function uses external wakeup feature of RTC_IO peripheral.
+ * It will work only if RTC peripherals are kept on during deep sleep.
+ *
+ * This feature can monitor any pin which is an RTC IO. Once the pin transitions
+ * into the state given by level argument, the chip will be woken up.
+ *
+ * @param gpio_num GPIO number used as wakeup source. Only GPIOs which are have RTC
+ * functionality can be used: 0,2,4,12-15,25-27,32-39.
+ * @param level input level which will trigger wakeup (0=low, 1=high)
+ * @return
+ * - ESP_OK on success
+ * - ESP_ERR_INVALID_ARG if either of the arguments is out of range
+ */
+esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
+
+/**
+ * @brief Enable wakeup using multiple pins
+ *
+ * This function uses external wakeup feature of RTC controller.
+ * It will work even if RTC peripherals are shut down during deep sleep.
+ *
+ * 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.
+ *
+ * @param mask bit mask of GPIO numbers which will cause wakeup. Only GPIOs
+ * 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
+ * @return
+ * - ESP_OK on success
+ * - ESP_ERR_INVALID_ARG if either of the arguments is out of range
+ */
+esp_err_t esp_deep_sleep_enable_ext1_wakeup(uint64_t mask, esp_ext1_wakeup_mode_t mode);
+
+
+/**
+ * @brief Get the bit mask of GPIOs which caused wakeup (ext1)
+ *
+ * If wakeup was caused by another source, this function will return 0.
+ *
+ * @return bit mask, if GPIOn caused wakeup, BIT(n) will be set
+ */
+uint64_t esp_deep_sleep_get_ext1_wakeup_status();
+
+/**
+ * @brief Enter deep sleep with the configured wakeup options
+ *
+ * This function does not return.
+ */
+void esp_deep_sleep_start() __attribute__((noreturn));
/**
* @brief Enter deep-sleep mode
void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub);
/**
- * @brief Return current wake from deep sleep stub, or NULL if
- * no stub is installed.
+ * @brief Get current wake from deep sleep stub
+ * @return Return current wake from deep sleep stub, or NULL if
+ * no stub is installed.
*/
esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void);
-/* The default esp-idf-provided esp_wake_deep_sleep() stub.
-
- See docs/deep-sleep-stub.rst for details.
-*/
+/**
+ * @brief The default esp-idf-provided esp_wake_deep_sleep() stub.
+ *
+ * See docs/deep-sleep-stub.rst for details.
+ */
void esp_default_wake_deep_sleep(void);
/**
#ifdef __cplusplus
}
#endif
-
-#endif /* __ESP_SYSTEM_H__ */