@@ -63,39 +63,42 @@ void alarm_reset(void) {
63
63
}
64
64
65
65
STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause (void ) {
66
- if (alarm_pin_pinalarm_woke_us_up ()) {
66
+ // First check if the modules remember what last woke up
67
+ if (alarm_pin_pinalarm_woke_this_cycle ()) {
67
68
return ESP_SLEEP_WAKEUP_GPIO ;
68
69
}
69
- if (alarm_time_timealarm_woke_us_up ()) {
70
+ if (alarm_time_timealarm_woke_this_cycle ()) {
70
71
return ESP_SLEEP_WAKEUP_TIMER ;
71
72
}
72
- if (alarm_touch_touchalarm_woke_us_up ()) {
73
+ if (alarm_touch_touchalarm_woke_this_cycle ()) {
73
74
return ESP_SLEEP_WAKEUP_TOUCHPAD ;
74
75
}
76
+ // If waking from true deep sleep, modules will have lost their state,
77
+ // so check the deep wakeup cause manually
75
78
return esp_sleep_get_wakeup_cause ();
76
79
}
77
80
78
81
bool common_hal_alarm_woken_from_sleep (void ) {
79
82
return _get_wakeup_cause () != ESP_SLEEP_WAKEUP_UNDEFINED ;
80
83
}
81
84
82
- // When called to populate the global dict, the module functions create new alarm objects.
83
- // Otherwise, they scan the existing alarms for matches.
84
- STATIC mp_obj_t _get_wake_alarm ( size_t n_alarms , const mp_obj_t * alarms ) {
85
+ mp_obj_t common_hal_alarm_create_wake_alarm ( void ) {
86
+ // If woken from deep sleep, create a copy alarm similar to what would have
87
+ // been passed in originally. Otherwise, just return none
85
88
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause ();
86
89
switch (cause ) {
87
90
case ESP_SLEEP_WAKEUP_TIMER : {
88
- return alarm_time_timealarm_get_wakeup_alarm ( n_alarms , alarms );
91
+ return alarm_time_timealarm_create_wakeup_alarm ( );
89
92
}
90
93
91
94
case ESP_SLEEP_WAKEUP_GPIO :
92
95
case ESP_SLEEP_WAKEUP_EXT0 :
93
96
case ESP_SLEEP_WAKEUP_EXT1 : {
94
- return alarm_pin_pinalarm_get_wakeup_alarm ( n_alarms , alarms );
97
+ return alarm_pin_pinalarm_create_wakeup_alarm ( );
95
98
}
96
99
97
100
case ESP_SLEEP_WAKEUP_TOUCHPAD : {
98
- return alarm_touch_touchalarm_get_wakeup_alarm ( n_alarms , alarms );
101
+ return alarm_touch_touchalarm_create_wakeup_alarm ( );
99
102
}
100
103
101
104
case ESP_SLEEP_WAKEUP_UNDEFINED :
@@ -106,44 +109,51 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
106
109
return mp_const_none ;
107
110
}
108
111
109
- // This function is used to create a new alarm object for the global dict after deep sleep,
110
- // rather than finding an existing one during runtime.
111
- mp_obj_t common_hal_alarm_get_wake_alarm (void ) {
112
- return _get_wake_alarm (0 , NULL );
113
- }
114
-
115
112
// Set up light sleep or deep sleep alarms.
116
113
STATIC void _setup_sleep_alarms (bool deep_sleep , size_t n_alarms , const mp_obj_t * alarms ) {
117
114
alarm_pin_pinalarm_set_alarms (deep_sleep , n_alarms , alarms );
118
115
alarm_time_timealarm_set_alarms (deep_sleep , n_alarms , alarms );
119
116
alarm_touch_touchalarm_set_alarm (deep_sleep , n_alarms , alarms );
120
117
}
121
118
122
- STATIC void _idle_until_alarm (void ) {
123
- // Poll for alarms.
119
+ mp_obj_t common_hal_alarm_light_sleep_until_alarms (size_t n_alarms , const mp_obj_t * alarms ) {
120
+ _setup_sleep_alarms (false, n_alarms , alarms );
121
+
122
+ mp_obj_t wake_alarm = mp_const_none ;
123
+
124
+ // We cannot esp_light_sleep_start() here because it shuts down all non-RTC peripherals.
124
125
while (!mp_hal_is_interrupted ()) {
125
126
RUN_BACKGROUND_TASKS ;
126
- // Allow ctrl-C interrupt.
127
+ // Detect if interrupt was alarm or ctrl-C interrupt.
127
128
if (common_hal_alarm_woken_from_sleep ()) {
128
- // This saves the return of common_hal_alarm_get_wake_alarm through Shared Bindings
129
- shared_alarm_save_wake_alarm ();
130
- return ;
129
+ esp_sleep_wakeup_cause_t cause = _get_wakeup_cause ();
130
+ switch (cause ) {
131
+ case ESP_SLEEP_WAKEUP_TIMER : {
132
+ wake_alarm = alarm_time_timealarm_find_triggered_alarm (n_alarms ,alarms );
133
+ break ;
134
+ }
135
+ case ESP_SLEEP_WAKEUP_GPIO : {
136
+ wake_alarm = alarm_pin_pinalarm_find_triggered_alarm (n_alarms ,alarms );
137
+ break ;
138
+ }
139
+ case ESP_SLEEP_WAKEUP_TOUCHPAD : {
140
+ wake_alarm = alarm_touch_touchalarm_find_triggered_alarm (n_alarms ,alarms );
141
+ break ;
142
+ }
143
+ default :
144
+ // Should not reach this, if all light sleep types are covered correctly
145
+ break ;
146
+ }
147
+ shared_alarm_save_wake_alarm (wake_alarm );
148
+ break ;
131
149
}
132
150
port_idle_until_interrupt ();
133
151
}
134
- }
135
-
136
- mp_obj_t common_hal_alarm_light_sleep_until_alarms (size_t n_alarms , const mp_obj_t * alarms ) {
137
- _setup_sleep_alarms (false, n_alarms , alarms );
138
-
139
- // We cannot esp_light_sleep_start() here because it shuts down all non-RTC peripherals.
140
- _idle_until_alarm ();
141
152
142
153
if (mp_hal_is_interrupted ()) {
143
154
return mp_const_none ; // Shouldn't be given to python code because exception handling should kick in.
144
155
}
145
156
146
- mp_obj_t wake_alarm = _get_wake_alarm (n_alarms , alarms );
147
157
alarm_reset ();
148
158
return wake_alarm ;
149
159
}
0 commit comments