From 7b12bc8837157b14007e0344c53d0d7a66640d6e Mon Sep 17 00:00:00 2001 From: eightycc Date: Tue, 6 May 2025 10:57:54 -0700 Subject: [PATCH 1/4] Fix port_get_raw_ticks() for these ports: o broadcom: return subticks o cxd56: return subticks only when pointer is non-null o litex: zero subticks, port is accurate only to ticks o raspberrypi: correct subtick calculation --- ports/broadcom/supervisor/port.c | 6 +++++- ports/cxd56/supervisor/port.c | 4 +++- ports/litex/supervisor/port.c | 3 +++ ports/raspberrypi/supervisor/port.c | 6 +++--- 4 files changed, 14 insertions(+), 5 deletions(-) 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) { From fcf7df857eb8600849408d208652f991fa34bcc9 Mon Sep 17 00:00:00 2001 From: eightycc Date: Tue, 6 May 2025 11:01:05 -0700 Subject: [PATCH 2/4] Improve mp_hal_delay_ms by implementing subtick resolution. --- supervisor/shared/tick.c | 30 ++++++++++++++++++++---------- supervisor/shared/tick.h | 7 +++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c index 24a06e622a181..dc646ae07b408 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); } +uint64_t supervisor_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,29 @@ 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 = supervisor_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); + remaining = end_subtick - supervisor_get_raw_subticks(); // 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); - // Idle until an interrupt happens. - port_idle_until_interrupt(); - remaining = end_tick - port_get_raw_ticks(NULL); + uint32_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 - supervisor_get_raw_subticks(); } } diff --git a/supervisor/shared/tick.h b/supervisor/shared/tick.h index fc18e8f762f55..9f303e17e7faa 100644 --- a/supervisor/shared/tick.h +++ b/supervisor/shared/tick.h @@ -33,6 +33,13 @@ extern uint32_t supervisor_ticks_ms32(void); */ extern uint64_t supervisor_ticks_ms64(void); +/** @brief Get 64-bit current time in subticks + * + * Time is returned as a 64-bit count of subticks where each subtick is 1/32768 + * of a second. + */ +extern uint64_t supervisor_get_raw_subticks(void); + extern void supervisor_enable_tick(void); extern void supervisor_disable_tick(void); From 61071cb41c7e81a0be11fb3ccec54a60de2398ab Mon Sep 17 00:00:00 2001 From: eightycc Date: Wed, 7 May 2025 08:06:41 -0700 Subject: [PATCH 3/4] Improve update to mp_hal_delay_ms: o Test for console interrupt during RUN_BACKGROUND_TASK o Handle signedness of remaining tick/subtick values correctly for very large delays o Improve comments --- supervisor/shared/tick.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c index dc646ae07b408..56021fc04f6b2 100644 --- a/supervisor/shared/tick.c +++ b/supervisor/shared/tick.c @@ -114,13 +114,14 @@ void mp_hal_delay_ms(mp_uint_t delay_ms) { // or the user. while (remaining > 0 && !mp_hal_is_interrupted()) { RUN_BACKGROUND_TASKS; - remaining = end_subtick - supervisor_get_raw_subticks(); - // 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; } - uint32_t remaining_ticks = remaining / 32; + // Recalculate remaining delay after running background tasks + remaining = end_subtick - supervisor_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. From b05e80e0b687f07752b6bdad5b949432d50ba7d3 Mon Sep 17 00:00:00 2001 From: eightycc Date: Wed, 7 May 2025 11:01:17 -0700 Subject: [PATCH 4/4] Make supervisor_get_raw_subticks a static function _get_raw_subticks. --- supervisor/shared/tick.c | 8 ++++---- supervisor/shared/tick.h | 7 ------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c index 56021fc04f6b2..e19b7c4e68134 100644 --- a/supervisor/shared/tick.c +++ b/supervisor/shared/tick.c @@ -85,7 +85,7 @@ void supervisor_tick(void) { background_callback_add(&tick_callback, supervisor_background_tick, NULL); } -uint64_t supervisor_get_raw_subticks(void) { +static uint64_t _get_raw_subticks(void) { uint64_t ticks; uint8_t subticks; ticks = port_get_raw_ticks(&subticks); @@ -104,7 +104,7 @@ uint32_t supervisor_ticks_ms32() { } void mp_hal_delay_ms(mp_uint_t delay_ms) { - uint64_t start_subtick = supervisor_get_raw_subticks(); + 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; @@ -119,7 +119,7 @@ void mp_hal_delay_ms(mp_uint_t delay_ms) { break; } // Recalculate remaining delay after running background tasks - remaining = end_subtick - supervisor_get_raw_subticks(); + 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) { @@ -127,7 +127,7 @@ void mp_hal_delay_ms(mp_uint_t delay_ms) { // Idle until an interrupt happens. port_idle_until_interrupt(); } - remaining = end_subtick - supervisor_get_raw_subticks(); + remaining = end_subtick - _get_raw_subticks(); } } diff --git a/supervisor/shared/tick.h b/supervisor/shared/tick.h index 9f303e17e7faa..fc18e8f762f55 100644 --- a/supervisor/shared/tick.h +++ b/supervisor/shared/tick.h @@ -33,13 +33,6 @@ extern uint32_t supervisor_ticks_ms32(void); */ extern uint64_t supervisor_ticks_ms64(void); -/** @brief Get 64-bit current time in subticks - * - * Time is returned as a 64-bit count of subticks where each subtick is 1/32768 - * of a second. - */ -extern uint64_t supervisor_get_raw_subticks(void); - extern void supervisor_enable_tick(void); extern void supervisor_disable_tick(void);