diff options
| author | Scott Shawcroft <scott@adafruit.com> | 2020-10-09 14:49:48 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-09 14:49:48 -0700 |
| commit | c7d87cea627f6eea827ae397e2e6549a9eb8fa53 (patch) | |
| tree | e2d6e1f79fc2fa1cea59255f515d41c307a5a1ee | |
| parent | 375676ff58c0cc887007dec4d7885c3120c53aa2 (diff) | |
| parent | 3ccf644dd0afd85ad8d8c6c67494cebab172b5a8 (diff) | |
Merge pull request #3532 from tannewt/samd21_autoreload
Fix autoreload on SAMD21
| -rw-r--r-- | ports/atmel-samd/supervisor/port.c | 58 |
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) { |
