@@ -85,6 +85,13 @@ void supervisor_tick(void) {
85
85
background_callback_add (& tick_callback , supervisor_background_tick , NULL );
86
86
}
87
87
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
+
88
95
uint64_t supervisor_ticks_ms64 () {
89
96
uint64_t result ;
90
97
result = port_get_raw_ticks (NULL );
@@ -97,26 +104,30 @@ uint32_t supervisor_ticks_ms32() {
97
104
}
98
105
99
106
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 ;
105
112
106
113
// Loop until we've waited long enough or we've been CTRL-Ced by autoreload
107
114
// or the user.
108
115
while (remaining > 0 && !mp_hal_is_interrupted ()) {
109
116
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 ()) {
114
119
break ;
115
120
}
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 ();
120
131
}
121
132
}
122
133
0 commit comments