42
42
43
43
#include "esp_sleep.h"
44
44
45
+ #include "components/soc/soc/esp32s2/include/soc/rtc_cntl_reg.h"
46
+ #include "components/driver/include/driver/uart.h"
47
+
45
48
// Singleton instance of SleepMemory.
46
49
const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
47
50
.base = {
48
51
.type = & alarm_sleep_memory_type ,
49
52
},
50
53
};
51
54
52
-
53
55
void alarm_reset (void ) {
54
56
alarm_time_timealarm_reset ();
57
+ alarm_pin_pin_alarm_reset ();
55
58
alarm_sleep_memory_reset ();
56
59
esp_sleep_disable_wakeup_source (ESP_SLEEP_WAKEUP_ALL );
57
60
}
@@ -60,6 +63,9 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
60
63
if (alarm_time_timealarm_woke_us_up ()) {
61
64
return ESP_SLEEP_WAKEUP_TIMER ;
62
65
}
66
+ if (alarm_pin_pin_alarm_woke_us_up ()) {
67
+ return ESP_SLEEP_WAKEUP_GPIO ;
68
+ }
63
69
64
70
return esp_sleep_get_wakeup_cause ();
65
71
}
@@ -69,14 +75,16 @@ bool alarm_woken_from_sleep(void) {
69
75
}
70
76
71
77
STATIC mp_obj_t _get_wake_alarm (size_t n_alarms , const mp_obj_t * alarms ) {
72
- switch (_get_wakeup_cause ()) {
78
+ esp_sleep_wakeup_cause_t cause = _get_wakeup_cause ();
79
+ switch (cause ) {
73
80
case ESP_SLEEP_WAKEUP_TIMER : {
74
81
return alarm_time_timealarm_get_wakeup_alarm (n_alarms , alarms );
75
82
}
76
83
77
- case ESP_SLEEP_WAKEUP_EXT0 : {
78
- // TODO: implement pin alarm wake.
79
- break ;
84
+ case ESP_SLEEP_WAKEUP_GPIO :
85
+ case ESP_SLEEP_WAKEUP_EXT0 :
86
+ case ESP_SLEEP_WAKEUP_EXT1 : {
87
+ return alarm_pin_pin_alarm_get_wakeup_alarm (n_alarms , alarms );
80
88
}
81
89
82
90
case ESP_SLEEP_WAKEUP_TOUCHPAD :
@@ -98,24 +106,8 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) {
98
106
99
107
// Set up light sleep or deep sleep alarms.
100
108
STATIC void _setup_sleep_alarms (bool deep_sleep , size_t n_alarms , const mp_obj_t * alarms ) {
101
- bool time_alarm_set = false;
102
- alarm_time_time_alarm_obj_t * time_alarm = MP_OBJ_NULL ;
103
-
104
- for (size_t i = 0 ; i < n_alarms ; i ++ ) {
105
- if (MP_OBJ_IS_TYPE (alarms [i ], & alarm_pin_pin_alarm_type )) {
106
- mp_raise_NotImplementedError (translate ("PinAlarm not yet implemented" ));
107
- } else if (MP_OBJ_IS_TYPE (alarms [i ], & alarm_time_time_alarm_type )) {
108
- if (time_alarm_set ) {
109
- mp_raise_ValueError (translate ("Only one alarm.time alarm can be set." ));
110
- }
111
- time_alarm = MP_OBJ_TO_PTR (alarms [i ]);
112
- time_alarm_set = true;
113
- }
114
- }
115
-
116
- if (time_alarm_set ) {
117
- alarm_time_timealarm_set_alarm (time_alarm );
118
- }
109
+ alarm_pin_pin_alarm_set_alarms (deep_sleep , n_alarms , alarms );
110
+ alarm_time_timealarm_set_alarms (deep_sleep , n_alarms , alarms );
119
111
}
120
112
121
113
STATIC void _idle_until_alarm (void ) {
@@ -134,18 +126,24 @@ STATIC void _idle_until_alarm(void) {
134
126
// Is it safe to do a light sleep? Check whether WiFi is on or there are
135
127
// other ongoing tasks that should not be shut down.
136
128
STATIC bool _light_sleep_ok (void ) {
137
- return !common_hal_wifi_radio_get_enabled (& common_hal_wifi_radio_obj ) && !supervisor_workflow_active ();
129
+ int64_t connecting_delay_ticks = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - port_get_raw_ticks (NULL );
130
+ return !common_hal_wifi_radio_get_enabled (& common_hal_wifi_radio_obj ) &&
131
+ !supervisor_workflow_active () &&
132
+ connecting_delay_ticks <= 0 ;
138
133
}
139
134
140
135
mp_obj_t common_hal_alarm_light_sleep_until_alarms (size_t n_alarms , const mp_obj_t * alarms ) {
141
136
_setup_sleep_alarms (false, n_alarms , alarms );
142
137
143
138
// Light sleep can break some functionality so only do it when possible. Otherwise we idle.
144
139
if (_light_sleep_ok ()) {
140
+ // Flush the UART to complete the log line.
141
+ uart_wait_tx_idle_polling (CONFIG_ESP_CONSOLE_UART_NUM );
145
142
esp_light_sleep_start ();
146
143
} else {
147
144
_idle_until_alarm ();
148
145
}
146
+
149
147
mp_obj_t wake_alarm = _get_wake_alarm (n_alarms , alarms );
150
148
alarm_reset ();
151
149
return wake_alarm ;
@@ -156,6 +154,7 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
156
154
}
157
155
158
156
void NORETURN alarm_enter_deep_sleep (void ) {
157
+ alarm_pin_pin_alarm_prepare_for_deep_sleep ();
159
158
// The ESP-IDF caches the deep sleep settings and applies them before sleep.
160
159
// We don't need to worry about resetting them in the interim.
161
160
esp_deep_sleep_start ();
0 commit comments