Skip to content

Improve resolution of mp_hal_delay_ms() to subticks. #10315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion ports/broadcom/supervisor/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion ports/cxd56/supervisor/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
3 changes: 3 additions & 0 deletions ports/litex/supervisor/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
6 changes: 3 additions & 3 deletions ports/raspberrypi/supervisor/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
37 changes: 24 additions & 13 deletions supervisor/shared/tick.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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();
}
}

Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy