Skip to content

Commit c7d87ce

Browse files
authored
Merge pull request adafruit#3532 from tannewt/samd21_autoreload
Fix autoreload on SAMD21
2 parents 375676f + 3ccf644 commit c7d87ce

File tree

1 file changed

+34
-24
lines changed
  • ports/atmel-samd/supervisor

1 file changed

+34
-24
lines changed

ports/atmel-samd/supervisor/port.c

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,33 @@ uint32_t port_get_saved_word(void) {
430430
static volatile uint64_t overflowed_ticks = 0;
431431
static 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+
433460
void 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-
476492
uint64_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.
508527
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) {
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

524534
void port_sleep_until_interrupt(void) {

0 commit comments

Comments
 (0)