- Wake up the ESP32 from deep sleep using a button press on a GPIO pin (using EXT0 wake-up).
- Check the state of the same GPIO in the wake stub function to determine if the button is being held for 4 seconds.
here is my code:
- #include <stdio.h>
- #include <string.h>
- #include "esp_sleep.h"
- #include "esp_attr.h"
- #include "rom/rtc.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "soc/rtc_cntl_reg.h"
- #include "soc/rtc_io_reg.h"
- #include "driver/rtc_io.h"
- #include "esp_wake_stub.h"
- #include "esp_system.h"
- #include "soc/rtc.h"
- #define BLE_BUTTON 5
- static size_t RTC_DATA_ATTR s_wake_count = 0;
- static int RTC_DATA_ATTR s_button_state = 0;
- static int RTC_DATA_ATTR s_in5 = 0;
- static void RTC_IRAM_ATTR wake_stub(void) {
- esp_default_wake_deep_sleep();
- uint32_t gpio_val;
- ESP_RTC_LOGI("wake stub function called");
- // Configure GPIO for input
- SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_MUX_SEL);
- SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_FUN_IE);
- SET_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, BIT(GPIO_NUM_5));
- // Read initial button state
- gpio_val = REG_READ(RTC_GPIO_IN_REG) >> RTC_GPIO_IN_NEXT_S;
- int button_pressed = (gpio_val >> BLE_BUTTON) & 0x1;
- ESP_RTC_LOGI("button pressed: %d", button_pressed);
- if (button_pressed == 0) {
- // Get the current time in microseconds
- int count = 0;
- // Wait for 4 seconds (4,000,000 microseconds)
- while (count < 4000000) {
- button_pressed = (REG_READ(RTC_GPIO_IN_REG) >> BLE_BUTTON) & 0x1;
- count++;
- if (button_pressed == 1) {
- ESP_RTC_LOGI("Button held for 4 seconds, waking up");
- return;
- }
- }
- }
- ESP_RTC_LOGI("wake stub: going to deep sleep");
- // Set stub entry, then going to deep sleep again.
- esp_wake_stub_sleep(&wake_stub);
- }
- void example_deep_sleep_register_ext0_wakeup(void) {
- printf("Enabling EXT0 wakeup on pin GPIO%d\n", BLE_BUTTON);
- esp_sleep_enable_ext0_wakeup(BLE_BUTTON, 0); // Wake on button press (low level)
- // Initialize and configure RTC GPIO for BLE_BUTTON
- rtc_gpio_init(BLE_BUTTON);
- rtc_gpio_set_direction(BLE_BUTTON, RTC_GPIO_MODE_INPUT_ONLY);
- rtc_gpio_pullup_en(BLE_BUTTON); // Enable pull-up resistor
- rtc_gpio_pulldown_dis(BLE_BUTTON); // Disable pull-down resistor
- rtc_gpio_hold_en(BLE_BUTTON); // Hold the GPIO configuration in deep sleep
- }
- void app_main(void) {
- if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
- printf("Wake up from deep sleep\n");
- } else {
- printf("Not a deep sleep wakeup\n");
- }
- // Register EXT0 GPIO as a wakeup source
- example_deep_sleep_register_ext0_wakeup();
- // Register the wake stub
- esp_set_deep_sleep_wake_stub(&wake_stub);
- // Enter deep sleep
- printf("Entering deep sleep\n");
- printf("Entering deep sleep\n");
- printf("Entering deep sleep\n");
- printf("Entering deep sleep\n");
- printf("Entering deep sleep\n");
- printf("Entering deep sleep\n");
- printf("Entering deep sleep\n");
- printf("Entering deep sleep\n");
- printf("Entering deep sleep\n");
- printf("Entering deep sleep\n");
- esp_deep_sleep_start();
- }
This is output:
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x1758
load:0x403c9700,len:0x4
load:0x403c9704,len:0xc00
load:0x403cc700,len:0x2e0c
entry 0x403c9908
I (27) boot: ESP-IDF v5.1.4-dirty 2nd stage bootloader
I (27) boot: compile time Sep 11 2024 10:23:34
I (27) boot: Multicore bootloader
I (30) boot: chip revision: v0.2
I (34) boot.esp32s3: Boot SPI Speed : 80MHz
I (39) boot.esp32s3: SPI Mode : DIO
I (44) boot.esp32s3: SPI Flash Size : 2MB
I (48) boot: Enabling RNG early entropy source...
I (54) boot: Partition Table:
I (57) boot: ## Label Usage Type ST Offset Length
I (65) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (72) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (80) boot: 2 factory factory app 00 00 00010000 00100000
I (87) boot: End of partition table
I (91) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=0a270h ( 41584) map
I (107) esp_image: segment 1: paddr=0001a298 vaddr=3fc92500 size=027b4h ( 10164) load
I (110) esp_image: segment 2: paddr=0001ca54 vaddr=40374000 size=035c4h ( 13764) load
I (120) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=1901ch (102428) map
I (144) esp_image: segment 4: paddr=00039044 vaddr=403775c4 size=0af20h ( 44832) load
I (154) esp_image: segment 5: paddr=00043f6c vaddr=50000000 size=000a8h ( 168) load
I (154) esp_image: segment 6: paddr=0004401c vaddr=600fe000 size=001cch ( 460) load
I (166) boot: Loaded app from partition at offset 0x10000
I (166) boot: Disabling RNG early entropy source...
I (182) cpu_start: Multicore app
I (183) cpu_start: Pro cpu up.
I (183) cpu_start: Starting app cpu, entry point is 0x40375438
0x40375438: call_start_cpu1 at /home/ahmet/esp/v5.1.4/esp-idf/components/esp_system/port/cpu_start.c:159
I (0) cpu_start: App cpu up.
I (201) cpu_start: Pro cpu start user code
I (201) cpu_start: cpu freq: 160000000 Hz
I (201) cpu_start: Application information:
I (204) cpu_start: Project name: wake_stub_buton_test
I (210) cpu_start: App version: 1
I (214) cpu_start: Compile time: Sep 11 2024 10:23:21
I (221) cpu_start: ELF file SHA256: c04de86e4ebc44a7...
I (226) cpu_start: ESP-IDF: v5.1.4-dirty
I (232) cpu_start: Min chip rev: v0.0
I (237) cpu_start: Max chip rev: v0.99
I (241) cpu_start: Chip rev: v0.2
I (246) heap_init: Initializing. RAM available for dynamic allocation:
I (253) heap_init: At 3FC95540 len 000541D0 (336 KiB): DRAM
I (260) heap_init: At 3FCE9710 len 00005724 (21 KiB): STACK/DRAM
I (266) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (272) heap_init: At 600FE1CC len 00001E1C (7 KiB): RTCRAM
I (280) spi_flash: detected chip: winbond
I (283) spi_flash: flash io: dio
W (287) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (301) sleep: Configure to isolate all GPIO pins in sleep state
I (307) sleep: Enable automatic switching of GPIO sleep configuration
I (315) app_start: Starting scheduler on CPU0
I (319) app_start: Starting scheduler on CPU1
I (319) main_task: Started on CPU0
I (329) main_task: Calling app_main()
Not a deep sleep wakeup
Enabling EXT0 wakeup on pin GPIO5
Entering deep sleep
Entering deep sleep
Entering deep sleep
Entering deep sleep
Entering deep sleep
Entering deep sleep
Entering deep sleep
Entering deep sleep
Entering deep sleep
Entering deep sleep
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x5 (DSLEEP),boot:0x8 (SPI_FAST_FLASH_BOOT)
pro cpu reset by JTAG
wake stub function called
button pressed: 0
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x7 (TG0WDT_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x600fe0cf
0x600fe0cf: wake_stub at /home/ahmet/esp_projects/wake_stub_buton_test/main/main.c:44