@@ -430,6 +430,33 @@ uint32_t port_get_saved_word(void) {
430430static volatile uint64_t overflowed_ticks = 0 ;
431431static volatile bool _ticks_enabled = false;
432432
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+
433460void RTC_Handler (void ) {
434461 uint32_t intflag = RTC -> MODE0 .INTFLAG .reg ;
435462 if (intflag & RTC_MODE0_INTFLAG_OVF ) {
@@ -452,7 +479,7 @@ void RTC_Handler(void) {
452479 supervisor_tick ();
453480 // Check _ticks_enabled again because a tick handler may have turned it off.
454481 if (_ticks_enabled ) {
455- port_interrupt_after_ticks (1 );
482+ _port_interrupt_after_ticks (1 );
456483 }
457484 }
458485 #endif
@@ -462,17 +489,6 @@ void RTC_Handler(void) {
462489 }
463490}
464491
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-
476492uint64_t port_get_raw_ticks (uint8_t * subticks ) {
477493 uint32_t current_ticks = _get_count ();
478494 if (subticks != NULL ) {
@@ -490,7 +506,7 @@ void port_enable_tick(void) {
490506 #endif
491507 #ifdef SAMD21
492508 _ticks_enabled = true;
493- port_interrupt_after_ticks (1 );
509+ _port_interrupt_after_ticks (1 );
494510 #endif
495511}
496512
@@ -505,20 +521,14 @@ void port_disable_tick(void) {
505521 #endif
506522}
507523
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.
508527void 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 ) {
516529 return ;
517530 }
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 );
522532}
523533
524534void port_sleep_until_interrupt (void ) {
0 commit comments