Skip to content

Commit e99cf6e

Browse files
committed
Rework sleep timing
It didn't account for background task time and could end up sleeping for way longer than it should because the RTC compare time had already passed.
1 parent 7e69d30 commit e99cf6e

3 files changed

Lines changed: 27 additions & 20 deletions

File tree

ports/atmel-samd/common-hal/pulseio/PulseIn.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ void pulsein_interrupt_handler(uint8_t channel) {
7979
// Grab the current time first.
8080
uint32_t current_overflow = overflow_count;
8181
Tc* tc = tc_insts[pulsein_tc_index];
82+
#ifdef SAMD51
83+
tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_READSYNC;
84+
while (tc->COUNT16.SYNCBUSY.bit.COUNT == 1 ||
85+
tc->COUNT16.CTRLBSET.bit.CMD == TC_CTRLBSET_CMD_READSYNC_Val) {}
86+
#endif
8287
uint32_t current_count = tc->COUNT16.COUNT.reg;
8388

8489
pulseio_pulsein_obj_t* self = get_eic_channel_data(channel);
@@ -119,6 +124,12 @@ void pulsein_interrupt_handler(uint8_t channel) {
119124
self->last_count = current_count;
120125
}
121126

127+
void pulsein_reset() {
128+
refcount = 0;
129+
pulsein_tc_index = 0xff;
130+
overflow_count = 0;
131+
}
132+
122133
void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
123134
const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) {
124135
if (!pin->has_extint) {
@@ -189,8 +200,6 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
189200
tc_enable_interrupts(pulsein_tc_index);
190201
tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_RETRIGGER;
191202

192-
//mp_printf(&mp_plat_print, "timer started\n");
193-
194203
overflow_count = 0;
195204
}
196205
refcount++;

ports/atmel-samd/supervisor/port.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ void reset_port(void) {
306306
#endif
307307
eic_reset();
308308
#if CIRCUITPY_PULSEIO
309+
pulsein_reset();
309310
pulseout_reset();
310311
pwmout_reset();
311312
#endif

supervisor/shared/tick.c

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,39 +79,36 @@ uint32_t supervisor_ticks_ms32() {
7979
extern void run_background_tasks(void);
8080

8181
void PLACE_IN_ITCM(supervisor_run_background_tasks_if_tick)() {
82-
uint8_t subticks;
83-
uint64_t now = port_get_raw_ticks(&subticks);
84-
85-
if (now == background_ticks && (subticks & 0x3) != 0) {
86-
return;
87-
}
88-
background_ticks = now;
89-
82+
// TODO: Add a global that can be set by anyone to indicate we should run background tasks. That
83+
// way we can short circuit the background tasks early. We used to do it based on time but it
84+
// breaks cases where we wake up for a short period and then sleep. If we skipped the last
85+
// background task or more before sleeping we may end up starving a task like USB.
9086
run_background_tasks();
9187
}
9288

93-
void supervisor_fake_tick() {
94-
uint32_t now = port_get_raw_ticks(NULL);
95-
background_ticks = (now - 1);
96-
}
97-
9889
void mp_hal_delay_ms(mp_uint_t delay) {
9990
uint64_t start_tick = port_get_raw_ticks(NULL);
10091
// Adjust the delay to ticks vs ms.
10192
delay = delay * 1024 / 1000;
102-
uint64_t duration = 0;
103-
port_interrupt_after_ticks(delay);
104-
while (duration < delay) {
93+
uint64_t end_tick = start_tick + delay;
94+
int64_t remaining = delay;
95+
while (remaining > 0) {
10596
RUN_BACKGROUND_TASKS;
10697
// Check to see if we've been CTRL-Ced by autoreload or the user.
10798
if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) ||
10899
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
109100
break;
110101
}
102+
remaining = end_tick - port_get_raw_ticks(NULL);
103+
// We break a bit early so we don't risk setting the alarm before the time when we call
104+
// sleep.
105+
if (remaining < 1) {
106+
break;
107+
}
108+
port_interrupt_after_ticks(remaining);
111109
// Sleep until an interrupt happens.
112110
port_sleep_until_interrupt();
113-
duration = (port_get_raw_ticks(NULL) - start_tick);
114-
port_interrupt_after_ticks(duration);
111+
remaining = end_tick - port_get_raw_ticks(NULL);
115112
}
116113
}
117114

0 commit comments

Comments
 (0)