1 /*
2 * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/kernel.h>
7 #include <zephyr/drivers/gpio.h>
8 #include <zephyr/sys/poweroff.h>
9 #include <esp_sleep.h>
10 #include <driver/rtc_io.h>
11
12 #define WAKEUP_TIME_SEC (20)
13
14 #ifdef CONFIG_EXAMPLE_EXT1_WAKEUP
15 #define EXT_WAKEUP_PIN_1 (2)
16 #define EXT_WAKEUP_PIN_2 (4)
17 #endif
18
19 #ifdef CONFIG_EXAMPLE_GPIO_WAKEUP
20 #if !DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(wakeup_button))
21 #error "Unsupported: wakeup-button alias is not defined"
22 #else
23 static const struct gpio_dt_spec wakeup_button = GPIO_DT_SPEC_GET(DT_ALIAS(wakeup_button), gpios);
24 #endif
25 #endif
26
main(void)27 int main(void)
28 {
29 switch (esp_sleep_get_wakeup_cause()) {
30 #ifdef CONFIG_EXAMPLE_EXT1_WAKEUP
31 case ESP_SLEEP_WAKEUP_EXT1:
32 {
33 uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status();
34
35 if (wakeup_pin_mask != 0) {
36 int pin = __builtin_ffsll(wakeup_pin_mask) - 1;
37
38 printk("Wake up from GPIO %d\n", pin);
39 } else {
40 printk("Wake up from GPIO\n");
41 }
42 break;
43 }
44 #endif /* CONFIG_EXAMPLE_EXT1_WAKEUP */
45 #ifdef CONFIG_EXAMPLE_GPIO_WAKEUP
46 case ESP_SLEEP_WAKEUP_GPIO:
47 {
48 uint64_t wakeup_pin_mask = esp_sleep_get_gpio_wakeup_status();
49
50 if (wakeup_pin_mask != 0) {
51 int pin = __builtin_ffsll(wakeup_pin_mask) - 1;
52
53 printk("Wake up from GPIO %d\n", pin);
54 } else {
55 printk("Wake up from GPIO\n");
56 }
57 break;
58 }
59 #endif /* CONFIG_EXAMPLE_GPIO_WAKEUP */
60 case ESP_SLEEP_WAKEUP_TIMER:
61 printk("Wake up from timer.\n");
62 break;
63 case ESP_SLEEP_WAKEUP_UNDEFINED:
64 default:
65 printk("Not a deep sleep reset\n");
66 }
67
68 k_busy_wait(1000000);
69
70 const int wakeup_time_sec = WAKEUP_TIME_SEC;
71
72 printk("Enabling timer wakeup, %ds\n", wakeup_time_sec);
73 esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000);
74
75 #ifdef CONFIG_EXAMPLE_EXT1_WAKEUP
76 const int ext_wakeup_pin_1 = EXT_WAKEUP_PIN_1;
77 const uint64_t ext_wakeup_pin_1_mask = BIT64(ext_wakeup_pin_1);
78 const int ext_wakeup_pin_2 = EXT_WAKEUP_PIN_2;
79 const uint64_t ext_wakeup_pin_2_mask = BIT64(ext_wakeup_pin_2);
80
81 printk("Enabling EXT1 wakeup on pins GPIO%d, GPIO%d\n",
82 ext_wakeup_pin_1, ext_wakeup_pin_2);
83 esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask,
84 ESP_EXT1_WAKEUP_ANY_HIGH);
85
86 /* enable pull-down on ext1 pins to avoid random wake-ups */
87 rtc_gpio_pullup_dis(EXT_WAKEUP_PIN_1);
88 rtc_gpio_pulldown_en(EXT_WAKEUP_PIN_1);
89 rtc_gpio_pullup_dis(EXT_WAKEUP_PIN_2);
90 rtc_gpio_pulldown_en(EXT_WAKEUP_PIN_2);
91 #endif /* CONFIG_EXAMPLE_EXT1_WAKEUP */
92 #ifdef CONFIG_EXAMPLE_GPIO_WAKEUP
93 if (!gpio_is_ready_dt(&wakeup_button)) {
94 printk("Error: wakeup button device %s is not ready\n", wakeup_button.port->name);
95 return 0;
96 }
97
98 int ret = gpio_pin_configure_dt(&wakeup_button, GPIO_INPUT);
99
100 if (ret != 0) {
101 printk("Error %d: failed to configure %s pin %d\n",
102 ret, wakeup_button.port->name, wakeup_button.pin);
103 return 0;
104 }
105
106 esp_deep_sleep_enable_gpio_wakeup(BIT(wakeup_button.pin), ESP_GPIO_WAKEUP_GPIO_HIGH);
107 printk("Enabling GPIO wakeup on pins GPIO%d\n", wakeup_button.pin);
108 #endif /* CONFIG_EXAMPLE_GPIO_WAKEUP */
109
110 printk("Powering off\n");
111 sys_poweroff();
112
113 return 0;
114 }
115