@@ -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+
8895uint64_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
99106void 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