|
72 | 72 |
|
73 | 73 | #include "supervisor/serial.h"
|
74 | 74 |
|
| 75 | +#include "tusb.h" |
| 76 | +#include <cmsis_compiler.h> |
| 77 | + |
75 | 78 | extern volatile bool mp_msc_enabled;
|
76 | 79 |
|
77 | 80 | STATIC void _tick_callback(uint alarm_num);
|
@@ -241,38 +244,48 @@ uint32_t port_get_saved_word(void) {
|
241 | 244 | return __scratch_x_start__;
|
242 | 245 | }
|
243 | 246 |
|
| 247 | +static volatile bool ticks_enabled; |
| 248 | + |
244 | 249 | uint64_t port_get_raw_ticks(uint8_t *subticks) {
|
245 | 250 | uint64_t microseconds = time_us_64();
|
246 | 251 | return 1024 * (microseconds / 1000000) + (microseconds % 1000000) / 977;
|
247 | 252 | }
|
248 | 253 |
|
249 | 254 | STATIC void _tick_callback(uint alarm_num) {
|
250 |
| - supervisor_tick(); |
251 |
| - hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977)); |
| 255 | + if (ticks_enabled) { |
| 256 | + supervisor_tick(); |
| 257 | + hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977)); |
| 258 | + } |
252 | 259 | }
|
253 | 260 |
|
254 | 261 | // Enable 1/1024 second tick.
|
255 | 262 | void port_enable_tick(void) {
|
| 263 | + ticks_enabled = true; |
256 | 264 | hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977));
|
257 | 265 | }
|
258 | 266 |
|
259 | 267 | // Disable 1/1024 second tick.
|
260 | 268 | void port_disable_tick(void) {
|
261 |
| - // hardware_alarm_cancel(0); |
| 269 | + // One additional _tick_callback may occur, but it will just return |
| 270 | + // whenever !ticks_enabled. Cancel is not called just in case |
| 271 | + // it could nuke a timeout set by port_interrupt_after_ticks. |
| 272 | + ticks_enabled = false; |
262 | 273 | }
|
263 | 274 |
|
264 | 275 | // This is called by sleep, we ignore it when our ticks are enabled because
|
265 | 276 | // they'll wake us up earlier. If we don't, we'll mess up ticks by overwriting
|
266 | 277 | // the next RTC wake up time.
|
267 | 278 | void port_interrupt_after_ticks(uint32_t ticks) {
|
| 279 | + if (!ticks_enabled) { |
| 280 | + hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), ticks * 977)); |
| 281 | + } |
268 | 282 | }
|
269 | 283 |
|
270 | 284 | void port_idle_until_interrupt(void) {
|
271 | 285 | common_hal_mcu_disable_interrupts();
|
272 |
| - if (!background_callback_pending()) { |
273 |
| - // TODO: Does not work when board is power-cycled. |
274 |
| - // asm volatile ("dsb 0xF" ::: "memory"); |
275 |
| - // __wfi(); |
| 286 | + if (!background_callback_pending() && !tud_task_event_ready()) { |
| 287 | + __DSB(); |
| 288 | + __WFI(); |
276 | 289 | }
|
277 | 290 | common_hal_mcu_enable_interrupts();
|
278 | 291 | }
|
|
0 commit comments