summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@adafruit.com>2020-10-09 14:49:48 -0700
committerGitHub <noreply@github.com>2020-10-09 14:49:48 -0700
commitc7d87cea627f6eea827ae397e2e6549a9eb8fa53 (patch)
treee2d6e1f79fc2fa1cea59255f515d41c307a5a1ee
parent375676ff58c0cc887007dec4d7885c3120c53aa2 (diff)
parent3ccf644dd0afd85ad8d8c6c67494cebab172b5a8 (diff)
Merge pull request #3532 from tannewt/samd21_autoreload
Fix autoreload on SAMD21
-rw-r--r--ports/atmel-samd/supervisor/port.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c
index 8d52c30c5..e69062296 100644
--- a/ports/atmel-samd/supervisor/port.c
+++ b/ports/atmel-samd/supervisor/port.c
@@ -430,6 +430,33 @@ uint32_t port_get_saved_word(void) {
static volatile uint64_t overflowed_ticks = 0;
static volatile bool _ticks_enabled = false;
+static uint32_t _get_count(void) {
+ #ifdef SAM_D5X_E5X
+ while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT)) != 0) {}
+ #endif
+ #ifdef SAMD21
+ while (RTC->MODE0.STATUS.bit.SYNCBUSY != 0) {}
+ #endif
+
+ return RTC->MODE0.COUNT.reg;
+}
+
+static void _port_interrupt_after_ticks(uint32_t ticks) {
+ uint32_t current_ticks = _get_count();
+ if (ticks > 1 << 28) {
+ // We'll interrupt sooner with an overflow.
+ return;
+ }
+#ifdef SAMD21
+ if (hold_interrupt) {
+ return;
+ }
+#endif
+ RTC->MODE0.COMP[0].reg = current_ticks + (ticks << 4);
+ RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
+ RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0;
+}
+
void RTC_Handler(void) {
uint32_t intflag = RTC->MODE0.INTFLAG.reg;
if (intflag & RTC_MODE0_INTFLAG_OVF) {
@@ -452,7 +479,7 @@ void RTC_Handler(void) {
supervisor_tick();
// Check _ticks_enabled again because a tick handler may have turned it off.
if (_ticks_enabled) {
- port_interrupt_after_ticks(1);
+ _port_interrupt_after_ticks(1);
}
}
#endif
@@ -462,17 +489,6 @@ void RTC_Handler(void) {
}
}
-static uint32_t _get_count(void) {
- #ifdef SAM_D5X_E5X
- while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT)) != 0) {}
- #endif
- #ifdef SAMD21
- while (RTC->MODE0.STATUS.bit.SYNCBUSY != 0) {}
- #endif
-
- return RTC->MODE0.COUNT.reg;
-}
-
uint64_t port_get_raw_ticks(uint8_t* subticks) {
uint32_t current_ticks = _get_count();
if (subticks != NULL) {
@@ -490,7 +506,7 @@ void port_enable_tick(void) {
#endif
#ifdef SAMD21
_ticks_enabled = true;
- port_interrupt_after_ticks(1);
+ _port_interrupt_after_ticks(1);
#endif
}
@@ -505,20 +521,14 @@ void port_disable_tick(void) {
#endif
}
+// This is called by sleep, we ignore it when our ticks are enabled because
+// they'll wake us up earlier. If we don't, we'll mess up ticks by overwriting
+// the next RTC wake up time.
void port_interrupt_after_ticks(uint32_t ticks) {
- uint32_t current_ticks = _get_count();
- if (ticks > 1 << 28) {
- // We'll interrupt sooner with an overflow.
- return;
- }
-#ifdef SAMD21
- if (hold_interrupt) {
+ if (_ticks_enabled) {
return;
}
-#endif
- RTC->MODE0.COMP[0].reg = current_ticks + (ticks << 4);
- RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
- RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0;
+ _port_interrupt_after_ticks(ticks);
}
void port_sleep_until_interrupt(void) {