ESP32S3 - how to read GPIO input from a wake stub
Posted: Fri Apr 01, 2022 9:48 pm
I'm testing on a ESP32S3-DevKitM-1. I can make GPIO outputs work from within my wake stub, but not GPIO inputs. Complete code is included below. What an I missing?
I have verified that the main application does read the same input GPIOs correctly.
I have verified that the main application does read the same input GPIOs correctly.
- /*
- * 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.
- }