diff --git a/ports/broadcom/supervisor/port.c b/ports/broadcom/supervisor/port.c index 33b20b7c8647a..83dd50f1b8b52 100644 --- a/ports/broadcom/supervisor/port.c +++ b/ports/broadcom/supervisor/port.c @@ -143,7 +143,11 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) { } COMPLETE_MEMORY_READS; uint64_t microseconds = hi << 32 | lo; - return 1024 * (microseconds / 1000000) + (microseconds % 1000000) / 977; + int64_t all_subticks = microseconds * 512 / 15625; + if (subticks != NULL) { + *subticks = all_subticks % 32; + } + return all_subticks / 32; } void TIMER_1_IRQHandler(void) { diff --git a/ports/cxd56/supervisor/port.c b/ports/cxd56/supervisor/port.c index 237013ff2bdab..75abcbf6d93e0 100644 --- a/ports/cxd56/supervisor/port.c +++ b/ports/cxd56/supervisor/port.c @@ -124,7 +124,9 @@ void board_timerhook(void) { uint64_t port_get_raw_ticks(uint8_t *subticks) { uint64_t count = cxd56_rtc_count(); - *subticks = count % 32; + if (subticks != NULL) { + *subticks = count % 32; + } return count / 32; } diff --git a/ports/litex/supervisor/port.c b/ports/litex/supervisor/port.c index 7009956c317ab..98fce16152e0b 100644 --- a/ports/litex/supervisor/port.c +++ b/ports/litex/supervisor/port.c @@ -114,6 +114,9 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) { common_hal_mcu_disable_interrupts(); uint64_t raw_tick_snapshot = raw_ticks; common_hal_mcu_enable_interrupts(); + if (subticks != NULL) { + *subticks = 0; + } return raw_tick_snapshot; } diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index 60d43e78ad361..f5bc67332af4b 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -491,11 +491,11 @@ static volatile bool ticks_enabled; static volatile bool _woken_up; uint64_t port_get_raw_ticks(uint8_t *subticks) { - uint64_t microseconds = time_us_64(); + int64_t all_subticks = time_us_64() * 512 / 15625; if (subticks != NULL) { - *subticks = (uint8_t)(((microseconds % 1000000) % 977) / 31); + *subticks = all_subticks % 32; } - return 1024 * (microseconds / 1000000) + (microseconds % 1000000) / 977; + return all_subticks / 32; } static void _tick_callback(uint alarm_num) { diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c index 24a06e622a181..e19b7c4e68134 100644 --- a/supervisor/shared/tick.c +++ b/supervisor/shared/tick.c @@ -85,6 +85,13 @@ void supervisor_tick(void) { background_callback_add(&tick_callback, supervisor_background_tick, NULL); } +static uint64_t _get_raw_subticks(void) { + uint64_t ticks; + uint8_t subticks; + ticks = port_get_raw_ticks(&subticks); + return (ticks << 5) | subticks; +} + uint64_t supervisor_ticks_ms64() { uint64_t result; result = port_get_raw_ticks(NULL); @@ -97,26 +104,30 @@ uint32_t supervisor_ticks_ms32() { } void mp_hal_delay_ms(mp_uint_t delay_ms) { - uint64_t start_tick = port_get_raw_ticks(NULL); - // Adjust the delay to ticks vs ms. - uint64_t delay_ticks = (delay_ms * (uint64_t)1024) / 1000; - uint64_t end_tick = start_tick + delay_ticks; - int64_t remaining = delay_ticks; + uint64_t start_subtick = _get_raw_subticks(); + // Convert delay from ms to subticks + uint64_t delay_subticks = (delay_ms * (uint64_t)32768) / 1000; + uint64_t end_subtick = start_subtick + delay_subticks; + int64_t remaining = delay_subticks; // Loop until we've waited long enough or we've been CTRL-Ced by autoreload // or the user. while (remaining > 0 && !mp_hal_is_interrupted()) { RUN_BACKGROUND_TASKS; - 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) { + // Exit if interrupted while running background tasks + if (mp_hal_is_interrupted()) { break; } - port_interrupt_after_ticks(remaining); - // Idle until an interrupt happens. - port_idle_until_interrupt(); - remaining = end_tick - port_get_raw_ticks(NULL); + // Recalculate remaining delay after running background tasks + remaining = end_subtick - _get_raw_subticks(); + // If remaining delay is less than 1 tick, idle loop until end of delay + int64_t remaining_ticks = remaining / 32; + if (remaining_ticks > 0) { + port_interrupt_after_ticks(remaining_ticks); + // Idle until an interrupt happens. + port_idle_until_interrupt(); + } + remaining = end_subtick - _get_raw_subticks(); } }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: