I have verified that the main application does read the same input GPIOs correctly.
Code: wake_test.c Select all
/*
* This sample illustrates writing and reading GPIO from a wake stub.
*
* The desired sequence is to
* 1) set GPIO_9 high
* 2) Read GPIO_10 and GPIO_11
* 3) set GPIO_9 low
*
* At this time the GPIO_10 and GPIO_11 read operations are not
* working correctly from the wake stub, but they do work correctly when
* the main application performs the same read.
*/
#include <stdio.h>
#include <string.h>
#include "esp_sleep.h"
#include "esp_attr.h"
#include "rom/rtc.h"
#include "rom/ets_sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/uart_reg.h"
#include "soc/timer_group_reg.h"
#include "driver/rtc_io.h"
// Pulse counter value, stored in RTC_SLOW_MEM
static size_t RTC_DATA_ATTR s_wake_count;
static int RTC_DATA_ATTR s_in10 = 0;
static int RTC_DATA_ATTR s_in11 = 0;
// Function which runs after exit from deep sleep
static void RTC_IRAM_ATTR wake_stub();
void app_main(void)
{
int l_in10 = 0;
int l_in11 = 0;
if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
printf("Wake up from deep sleep: count = %d\n", s_wake_count);
} else {
s_wake_count = 0;
printf("Not a deep sleep wake up\n");
}
// check GPIO 10 & 11 from application
rtc_gpio_init(GPIO_NUM_10);
rtc_gpio_set_direction(GPIO_NUM_10, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_pulldown_dis(GPIO_NUM_10);
rtc_gpio_pullup_dis(GPIO_NUM_10);
rtc_gpio_hold_en(GPIO_NUM_10);
rtc_gpio_init(GPIO_NUM_11);
rtc_gpio_set_direction(GPIO_NUM_11, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_pulldown_dis(GPIO_NUM_11);
rtc_gpio_pullup_dis(GPIO_NUM_11);
rtc_gpio_hold_en(GPIO_NUM_11);
l_in10 = rtc_gpio_get_level(GPIO_NUM_10);
l_in11 = rtc_gpio_get_level(GPIO_NUM_11);
printf("Wake stub readings: 10 = %d, 11 = %d\n", s_in10, s_in11);
printf("App readings: 10 = %d, 11 = %d\n", l_in10, l_in11);
printf("Going to deep sleep in 2 second for 5 seconds\n");
ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(5 * 1000000));
vTaskDelay(2000/portTICK_PERIOD_MS);
// Set the wake stub function
esp_set_deep_sleep_wake_stub(&wake_stub);
// Enter deep sleep
esp_deep_sleep_start();
}
static void RTC_IRAM_ATTR wake_stub()
{
uint32_t gpio_val;
// Increment the wake counter
s_wake_count++;
// Output - set RTC mux
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_MUX_SEL);
// Output - clear the HOLD bit
CLEAR_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, BIT(GPIO_NUM_9));
// Output - enable GPIO output
REG_WRITE(RTC_GPIO_ENABLE_W1TS_REG, BIT(RTC_GPIO_ENABLE_W1TS_S + GPIO_NUM_9));
// Ouput - set the GPIO output high
REG_WRITE(RTC_GPIO_OUT_W1TS_REG, BIT(RTC_GPIO_OUT_DATA_W1TS_S + GPIO_NUM_9));
// Input - set RTC mux
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD10_REG, RTC_IO_TOUCH_PAD10_MUX_SEL);
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD11_REG, RTC_IO_TOUCH_PAD11_MUX_SEL);
// Input - enable
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD10_REG, RTC_IO_TOUCH_PAD10_FUN_IE);
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD11_REG, RTC_IO_TOUCH_PAD11_FUN_IE);
// Input - set the hold bit
SET_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, BIT(GPIO_NUM_10));
SET_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, BIT(GPIO_NUM_11));
// Input - read the GPIO input register
gpio_val = REG_READ(RTC_GPIO_IN_REG) >> RTC_GPIO_IN_NEXT_S;
s_in10 = (gpio_val >> GPIO_NUM_10) & 0x1;
s_in11 = (gpio_val >> GPIO_NUM_11) & 0x1;
// Ouput - set the GPIO output low again
REG_WRITE(RTC_GPIO_OUT_W1TC_REG, BIT(RTC_GPIO_OUT_DATA_W1TC_S + GPIO_NUM_9));
// On revision 0 of ESP32, this function must be called:
esp_default_wake_deep_sleep();
// Return from the wake stub function to continue
// booting the firmware.
return;
// never reaches here.
}