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.
This commit is contained in:
parent
7e69d30c02
commit
e99cf6e441
@ -79,6 +79,11 @@ void pulsein_interrupt_handler(uint8_t channel) {
|
||||
// Grab the current time first.
|
||||
uint32_t current_overflow = overflow_count;
|
||||
Tc* tc = tc_insts[pulsein_tc_index];
|
||||
#ifdef SAMD51
|
||||
tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_READSYNC;
|
||||
while (tc->COUNT16.SYNCBUSY.bit.COUNT == 1 ||
|
||||
tc->COUNT16.CTRLBSET.bit.CMD == TC_CTRLBSET_CMD_READSYNC_Val) {}
|
||||
#endif
|
||||
uint32_t current_count = tc->COUNT16.COUNT.reg;
|
||||
|
||||
pulseio_pulsein_obj_t* self = get_eic_channel_data(channel);
|
||||
@ -119,6 +124,12 @@ void pulsein_interrupt_handler(uint8_t channel) {
|
||||
self->last_count = current_count;
|
||||
}
|
||||
|
||||
void pulsein_reset() {
|
||||
refcount = 0;
|
||||
pulsein_tc_index = 0xff;
|
||||
overflow_count = 0;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
|
||||
const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) {
|
||||
if (!pin->has_extint) {
|
||||
@ -189,8 +200,6 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
|
||||
tc_enable_interrupts(pulsein_tc_index);
|
||||
tc->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_RETRIGGER;
|
||||
|
||||
//mp_printf(&mp_plat_print, "timer started\n");
|
||||
|
||||
overflow_count = 0;
|
||||
}
|
||||
refcount++;
|
||||
|
@ -306,6 +306,7 @@ void reset_port(void) {
|
||||
#endif
|
||||
eic_reset();
|
||||
#if CIRCUITPY_PULSEIO
|
||||
pulsein_reset();
|
||||
pulseout_reset();
|
||||
pwmout_reset();
|
||||
#endif
|
||||
|
@ -79,39 +79,36 @@ uint32_t supervisor_ticks_ms32() {
|
||||
extern void run_background_tasks(void);
|
||||
|
||||
void PLACE_IN_ITCM(supervisor_run_background_tasks_if_tick)() {
|
||||
uint8_t subticks;
|
||||
uint64_t now = port_get_raw_ticks(&subticks);
|
||||
|
||||
if (now == background_ticks && (subticks & 0x3) != 0) {
|
||||
return;
|
||||
}
|
||||
background_ticks = now;
|
||||
|
||||
// TODO: Add a global that can be set by anyone to indicate we should run background tasks. That
|
||||
// way we can short circuit the background tasks early. We used to do it based on time but it
|
||||
// breaks cases where we wake up for a short period and then sleep. If we skipped the last
|
||||
// background task or more before sleeping we may end up starving a task like USB.
|
||||
run_background_tasks();
|
||||
}
|
||||
|
||||
void supervisor_fake_tick() {
|
||||
uint32_t now = port_get_raw_ticks(NULL);
|
||||
background_ticks = (now - 1);
|
||||
}
|
||||
|
||||
void mp_hal_delay_ms(mp_uint_t delay) {
|
||||
uint64_t start_tick = port_get_raw_ticks(NULL);
|
||||
// Adjust the delay to ticks vs ms.
|
||||
delay = delay * 1024 / 1000;
|
||||
uint64_t duration = 0;
|
||||
port_interrupt_after_ticks(delay);
|
||||
while (duration < delay) {
|
||||
uint64_t end_tick = start_tick + delay;
|
||||
int64_t remaining = delay;
|
||||
while (remaining > 0) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
// Check to see if we've been CTRL-Ced by autoreload or the user.
|
||||
if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) ||
|
||||
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
|
||||
break;
|
||||
}
|
||||
remaining = end_tick - port_get_raw_ticks(NULL);
|
||||
// We break a bit early so we don't risk setting the alarm before the time when we call
|
||||
// sleep.
|
||||
if (remaining < 1) {
|
||||
break;
|
||||
}
|
||||
port_interrupt_after_ticks(remaining);
|
||||
// Sleep until an interrupt happens.
|
||||
port_sleep_until_interrupt();
|
||||
duration = (port_get_raw_ticks(NULL) - start_tick);
|
||||
port_interrupt_after_ticks(duration);
|
||||
remaining = end_tick - port_get_raw_ticks(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user