38
38
39
39
// This variable stores whether a PinAlarm woke in light sleep or fake deep sleep
40
40
// It CANNOT detect if the program woke from deep sleep.
41
- STATIC bool woke_up ;
42
- STATIC bool deep_wkup_enabled ;
41
+ STATIC volatile bool woke_up ;
42
+ // TODO: replace pinalarm_on with SAMD_ALARM_FLAG bit flags
43
+ STATIC volatile bool pinalarm_on ;
43
44
44
45
// TODO: Create tables here reserving IRQ instances, and for the IRQ
45
46
// callback to store what pin triggered the interrupt
@@ -55,12 +56,16 @@ void pin_alarm_callback(uint8_t num) { // parameters can be changed
55
56
// Turn off interrupts while in handler
56
57
// printf("Woke up from pin!!\n");
57
58
// printf("EIC Flags: %lu\n",EIC->INTFLAG.reg);
58
-
59
- // QUESTION: How to reference the correct EIC?
60
- // set_eic_handler(self->channel, EIC_HANDLER_NO_INTERRUPT);
61
- // turn_off_eic_channel(self->channel);
62
- // reset_pin_number(self->pin);
63
- woke_up = true;
59
+ if (pinalarm_on ) {
60
+ // clear flag and interrupt setting
61
+ RTC -> MODE0 .INTENCLR .reg = RTC_MODE0_INTENCLR_TAMPER ;
62
+ pinalarm_on = false;
63
+ // QUESTION: How to reference the correct EIC?
64
+ // set_eic_handler(self->channel, EIC_HANDLER_NO_INTERRUPT);
65
+ // turn_off_eic_channel(self->channel);
66
+ // reset_pin_number(self->pin);
67
+ woke_up = true;
68
+ }
64
69
}
65
70
66
71
void common_hal_alarm_pin_pinalarm_construct (alarm_pin_pinalarm_obj_t * self , const mcu_pin_obj_t * pin , bool value , bool edge , bool pull ) {
@@ -89,9 +94,13 @@ void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, con
89
94
90
95
gpio_set_pin_function (pin -> number , GPIO_PIN_FUNCTION_A );
91
96
if (self -> pull ) {
92
- gpio_set_pin_pull_mode (pin -> number , GPIO_PULL_UP );
93
- } else {
94
- gpio_set_pin_pull_mode (pin -> number , GPIO_PULL_DOWN );
97
+ if (self -> value ) {
98
+ // detect rising edge means pull down
99
+ gpio_set_pin_pull_mode (pin -> number , GPIO_PULL_DOWN );
100
+ } else {
101
+ // detect falling edge means pull up
102
+ gpio_set_pin_pull_mode (pin -> number , GPIO_PULL_UP );
103
+ }
95
104
}
96
105
set_eic_channel_data (self -> channel , (void * )self );
97
106
@@ -107,7 +116,6 @@ bool common_hal_alarm_pin_pinalarm_get_value(alarm_pin_pinalarm_obj_t *self) {
107
116
}
108
117
109
118
bool common_hal_alarm_pin_pinalarm_get_edge (alarm_pin_pinalarm_obj_t * self ) {
110
- // TODO: is SAMD edge or level only?
111
119
return true;
112
120
}
113
121
@@ -116,9 +124,8 @@ bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) {
116
124
}
117
125
118
126
bool alarm_pin_pinalarm_woke_this_cycle (void ) {
119
- if (RTC -> MODE0 .INTFLAG .bit .TAMPER ) {
127
+ if (pinalarm_on && RTC -> MODE0 .INTFLAG .bit .TAMPER ) {
120
128
woke_up = true;
121
- RTC -> MODE0 .INTENCLR .bit .TAMPER = 1 ; // clear flag and interrupt setting
122
129
}
123
130
return woke_up ;
124
131
}
@@ -135,9 +142,6 @@ mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t
135
142
// TODO: Determine whether any pins have been marked as
136
143
// triggering the alarm (using the static vars at
137
144
// start of file) and if so return that alarm.
138
-
139
-
140
-
141
145
}
142
146
// Return nothing if no matching alarms are found.
143
147
return mp_const_none ;
@@ -159,9 +163,22 @@ void alarm_pin_pinalarm_reset(void) {
159
163
// sure to clear any reserved tables, deinit both PORT and TAMPER
160
164
// settings, etc. If flags are set to indicate this module is in
161
165
// use, reset them.
162
-
166
+ pinalarm_on = false;
167
+ woke_up = false;
163
168
// Disable TAMPER interrupt
164
169
RTC -> MODE0 .INTENCLR .bit .TAMPER = 1 ;
170
+ // Disable TAMPER control
171
+ common_hal_mcu_disable_interrupts ();
172
+ RTC -> MODE0 .CTRLA .bit .ENABLE = 0 ; // Disable the RTC
173
+ while (RTC -> MODE0 .SYNCBUSY .bit .ENABLE ) { // Wait for synchronization
174
+ ;
175
+ }
176
+ RTC -> MODE0 .TAMPCTRL .reg = 0 ; // reset everything
177
+ RTC -> MODE0 .CTRLA .bit .ENABLE = 1 ; // Enable the RTC
178
+ while (RTC -> MODE0 .SYNCBUSY .bit .ENABLE ) { // Wait for synchronization
179
+ ;
180
+ }
181
+ common_hal_mcu_enable_interrupts ();
165
182
}
166
183
167
184
void alarm_pin_pinalarm_set_alarms (bool deep_sleep , size_t n_alarms , const mp_obj_t * alarms ) {
@@ -177,9 +194,25 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob
177
194
alarm -> pin != & pin_PA02 ) {
178
195
mp_raise_ValueError (translate ("Pin cannot wake from Deep Sleep" ));
179
196
}
180
- deep_wkup_enabled = true;
197
+ pinalarm_on = true;
181
198
// Set tamper interrupt so deep sleep knows that's the intent
182
199
RTC -> MODE0 .INTENSET .reg = RTC_MODE0_INTENSET_TAMPER ;
200
+ common_hal_mcu_disable_interrupts ();
201
+ RTC -> MODE0 .CTRLA .bit .ENABLE = 0 ; // Disable the RTC
202
+ while (RTC -> MODE0 .SYNCBUSY .bit .ENABLE ) { // Wait for synchronization
203
+ ;
204
+ }
205
+ // TODO: map requested pin to limited selection of TAMPER pins
206
+ // PA02 is n=2: IN2, LVL2, etc...
207
+ RTC -> MODE0 .TAMPCTRL .bit .DEBNC2 = 1 ; // Edge triggered when INn is stable for 4 CLK_RTC_DEB periods
208
+ RTC -> MODE0 .TAMPCTRL .bit .TAMLVL2 = alarm -> value ; // rising or falling edge
209
+ RTC -> MODE0 .TAMPCTRL .bit .IN2ACT = 0x1 ; // WAKE on IN2 (doesn't save timestamp)
210
+ common_hal_mcu_enable_interrupts ();
211
+ RTC -> MODE0 .INTENSET .reg = RTC_MODE0_INTENSET_TAMPER ;
212
+ RTC -> MODE0 .CTRLA .bit .ENABLE = 1 ; // Enable the RTC
213
+ while (RTC -> MODE0 .SYNCBUSY .bit .ENABLE ) { // Wait for synchronization
214
+ ;
215
+ }
183
216
// TODO: Set up deep sleep alarms.
184
217
// For deep sleep alarms, first check if the
185
218
// alarm pin value is valid for RTC->TAMPER. Ensure
0 commit comments