Skip to content

Commit 07ec0c6

Browse files
authored
Merge pull request #10315 from eightycc/issue-9693
Improve resolution of mp_hal_delay_ms() to subticks.
2 parents df7903d + b05e80e commit 07ec0c6

File tree

5 files changed

+38
-18
lines changed

5 files changed

+38
-18
lines changed

ports/broadcom/supervisor/port.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,11 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) {
143143
}
144144
COMPLETE_MEMORY_READS;
145145
uint64_t microseconds = hi << 32 | lo;
146-
return 1024 * (microseconds / 1000000) + (microseconds % 1000000) / 977;
146+
int64_t all_subticks = microseconds * 512 / 15625;
147+
if (subticks != NULL) {
148+
*subticks = all_subticks % 32;
149+
}
150+
return all_subticks / 32;
147151
}
148152

149153
void TIMER_1_IRQHandler(void) {

ports/cxd56/supervisor/port.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ void board_timerhook(void) {
124124

125125
uint64_t port_get_raw_ticks(uint8_t *subticks) {
126126
uint64_t count = cxd56_rtc_count();
127-
*subticks = count % 32;
127+
if (subticks != NULL) {
128+
*subticks = count % 32;
129+
}
128130

129131
return count / 32;
130132
}

ports/litex/supervisor/port.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) {
114114
common_hal_mcu_disable_interrupts();
115115
uint64_t raw_tick_snapshot = raw_ticks;
116116
common_hal_mcu_enable_interrupts();
117+
if (subticks != NULL) {
118+
*subticks = 0;
119+
}
117120
return raw_tick_snapshot;
118121
}
119122

ports/raspberrypi/supervisor/port.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,11 +491,11 @@ static volatile bool ticks_enabled;
491491
static volatile bool _woken_up;
492492

493493
uint64_t port_get_raw_ticks(uint8_t *subticks) {
494-
uint64_t microseconds = time_us_64();
494+
int64_t all_subticks = time_us_64() * 512 / 15625;
495495
if (subticks != NULL) {
496-
*subticks = (uint8_t)(((microseconds % 1000000) % 977) / 31);
496+
*subticks = all_subticks % 32;
497497
}
498-
return 1024 * (microseconds / 1000000) + (microseconds % 1000000) / 977;
498+
return all_subticks / 32;
499499
}
500500

501501
static void _tick_callback(uint alarm_num) {

supervisor/shared/tick.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ void supervisor_tick(void) {
8585
background_callback_add(&tick_callback, supervisor_background_tick, NULL);
8686
}
8787

88+
static uint64_t _get_raw_subticks(void) {
89+
uint64_t ticks;
90+
uint8_t subticks;
91+
ticks = port_get_raw_ticks(&subticks);
92+
return (ticks << 5) | subticks;
93+
}
94+
8895
uint64_t supervisor_ticks_ms64() {
8996
uint64_t result;
9097
result = port_get_raw_ticks(NULL);
@@ -97,26 +104,30 @@ uint32_t supervisor_ticks_ms32() {
97104
}
98105

99106
void mp_hal_delay_ms(mp_uint_t delay_ms) {
100-
uint64_t start_tick = port_get_raw_ticks(NULL);
101-
// Adjust the delay to ticks vs ms.
102-
uint64_t delay_ticks = (delay_ms * (uint64_t)1024) / 1000;
103-
uint64_t end_tick = start_tick + delay_ticks;
104-
int64_t remaining = delay_ticks;
107+
uint64_t start_subtick = _get_raw_subticks();
108+
// Convert delay from ms to subticks
109+
uint64_t delay_subticks = (delay_ms * (uint64_t)32768) / 1000;
110+
uint64_t end_subtick = start_subtick + delay_subticks;
111+
int64_t remaining = delay_subticks;
105112

106113
// Loop until we've waited long enough or we've been CTRL-Ced by autoreload
107114
// or the user.
108115
while (remaining > 0 && !mp_hal_is_interrupted()) {
109116
RUN_BACKGROUND_TASKS;
110-
remaining = end_tick - port_get_raw_ticks(NULL);
111-
// We break a bit early so we don't risk setting the alarm before the time when we call
112-
// sleep.
113-
if (remaining < 1) {
117+
// Exit if interrupted while running background tasks
118+
if (mp_hal_is_interrupted()) {
114119
break;
115120
}
116-
port_interrupt_after_ticks(remaining);
117-
// Idle until an interrupt happens.
118-
port_idle_until_interrupt();
119-
remaining = end_tick - port_get_raw_ticks(NULL);
121+
// Recalculate remaining delay after running background tasks
122+
remaining = end_subtick - _get_raw_subticks();
123+
// If remaining delay is less than 1 tick, idle loop until end of delay
124+
int64_t remaining_ticks = remaining / 32;
125+
if (remaining_ticks > 0) {
126+
port_interrupt_after_ticks(remaining_ticks);
127+
// Idle until an interrupt happens.
128+
port_idle_until_interrupt();
129+
}
130+
remaining = end_subtick - _get_raw_subticks();
120131
}
121132
}
122133

0 commit comments

Comments
 (0)