@@ -430,6 +430,33 @@ uint32_t port_get_saved_word(void) {
430
430
static volatile uint64_t overflowed_ticks = 0 ;
431
431
static volatile bool _ticks_enabled = false;
432
432
433
+ static uint32_t _get_count (void ) {
434
+ #ifdef SAM_D5X_E5X
435
+ while ((RTC -> MODE0 .SYNCBUSY .reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT )) != 0 ) {}
436
+ #endif
437
+ #ifdef SAMD21
438
+ while (RTC -> MODE0 .STATUS .bit .SYNCBUSY != 0 ) {}
439
+ #endif
440
+
441
+ return RTC -> MODE0 .COUNT .reg ;
442
+ }
443
+
444
+ static void _port_interrupt_after_ticks (uint32_t ticks ) {
445
+ uint32_t current_ticks = _get_count ();
446
+ if (ticks > 1 << 28 ) {
447
+ // We'll interrupt sooner with an overflow.
448
+ return ;
449
+ }
450
+ #ifdef SAMD21
451
+ if (hold_interrupt ) {
452
+ return ;
453
+ }
454
+ #endif
455
+ RTC -> MODE0 .COMP [0 ].reg = current_ticks + (ticks << 4 );
456
+ RTC -> MODE0 .INTFLAG .reg = RTC_MODE0_INTFLAG_CMP0 ;
457
+ RTC -> MODE0 .INTENSET .reg = RTC_MODE0_INTENSET_CMP0 ;
458
+ }
459
+
433
460
void RTC_Handler (void ) {
434
461
uint32_t intflag = RTC -> MODE0 .INTFLAG .reg ;
435
462
if (intflag & RTC_MODE0_INTFLAG_OVF ) {
@@ -452,7 +479,7 @@ void RTC_Handler(void) {
452
479
supervisor_tick ();
453
480
// Check _ticks_enabled again because a tick handler may have turned it off.
454
481
if (_ticks_enabled ) {
455
- port_interrupt_after_ticks (1 );
482
+ _port_interrupt_after_ticks (1 );
456
483
}
457
484
}
458
485
#endif
@@ -462,17 +489,6 @@ void RTC_Handler(void) {
462
489
}
463
490
}
464
491
465
- static uint32_t _get_count (void ) {
466
- #ifdef SAM_D5X_E5X
467
- while ((RTC -> MODE0 .SYNCBUSY .reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT )) != 0 ) {}
468
- #endif
469
- #ifdef SAMD21
470
- while (RTC -> MODE0 .STATUS .bit .SYNCBUSY != 0 ) {}
471
- #endif
472
-
473
- return RTC -> MODE0 .COUNT .reg ;
474
- }
475
-
476
492
uint64_t port_get_raw_ticks (uint8_t * subticks ) {
477
493
uint32_t current_ticks = _get_count ();
478
494
if (subticks != NULL ) {
@@ -490,7 +506,7 @@ void port_enable_tick(void) {
490
506
#endif
491
507
#ifdef SAMD21
492
508
_ticks_enabled = true;
493
- port_interrupt_after_ticks (1 );
509
+ _port_interrupt_after_ticks (1 );
494
510
#endif
495
511
}
496
512
@@ -505,20 +521,14 @@ void port_disable_tick(void) {
505
521
#endif
506
522
}
507
523
524
+ // This is called by sleep, we ignore it when our ticks are enabled because
525
+ // they'll wake us up earlier. If we don't, we'll mess up ticks by overwriting
526
+ // the next RTC wake up time.
508
527
void port_interrupt_after_ticks (uint32_t ticks ) {
509
- uint32_t current_ticks = _get_count ();
510
- if (ticks > 1 << 28 ) {
511
- // We'll interrupt sooner with an overflow.
512
- return ;
513
- }
514
- #ifdef SAMD21
515
- if (hold_interrupt ) {
528
+ if (_ticks_enabled ) {
516
529
return ;
517
530
}
518
- #endif
519
- RTC -> MODE0 .COMP [0 ].reg = current_ticks + (ticks << 4 );
520
- RTC -> MODE0 .INTFLAG .reg = RTC_MODE0_INTFLAG_CMP0 ;
521
- RTC -> MODE0 .INTENSET .reg = RTC_MODE0_INTENSET_CMP0 ;
531
+ _port_interrupt_after_ticks (ticks );
522
532
}
523
533
524
534
void port_sleep_until_interrupt (void ) {
0 commit comments