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