diff options
| author | Scott Shawcroft <scott@tannewt.org> | 2020-03-17 12:10:35 -0700 |
|---|---|---|
| committer | Scott Shawcroft <scott@tannewt.org> | 2020-03-17 12:10:35 -0700 |
| commit | d9e68156b23cfca47592c5672e69622d6071ff60 (patch) | |
| tree | 363ad2d3282d5c4d4dfa62c45eb1e10a79b4b7a0 /ports | |
| parent | 4297ae2d0be7fd3b6c61a611c5598cb438b54b8f (diff) | |
fix up SAMD21 sleep
Diffstat (limited to 'ports')
| -rw-r--r-- | ports/atmel-samd/common-hal/touchio/TouchIn.c | 1 | ||||
| m--------- | ports/atmel-samd/peripherals | 0 | ||||
| -rw-r--r-- | ports/atmel-samd/supervisor/internal_flash.c | 3 | ||||
| -rw-r--r-- | ports/atmel-samd/supervisor/port.c | 63 |
4 files changed, 56 insertions, 11 deletions
diff --git a/ports/atmel-samd/common-hal/touchio/TouchIn.c b/ports/atmel-samd/common-hal/touchio/TouchIn.c index 908d8d722..b2fcc6cde 100644 --- a/ports/atmel-samd/common-hal/touchio/TouchIn.c +++ b/ports/atmel-samd/common-hal/touchio/TouchIn.c @@ -42,7 +42,6 @@ #include "samd/clocks.h" #include "samd/pins.h" -#include "tick.h" #include "adafruit_ptc.h" bool touch_enabled = false; diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals -Subproject df39529b42fbc43db3c9b5724dfb2d6c562e848 +Subproject bfbc88fd6b2e2bb8f5e88836c0ba46eb80f9757 diff --git a/ports/atmel-samd/supervisor/internal_flash.c b/ports/atmel-samd/supervisor/internal_flash.c index a8ff5adfa..9c8ff990e 100644 --- a/ports/atmel-samd/supervisor/internal_flash.c +++ b/ports/atmel-samd/supervisor/internal_flash.c @@ -41,6 +41,7 @@ #endif #include "hal/include/hal_flash.h" +#include "supervisor/flash.h" #include "supervisor/shared/rgb_led_status.h" static struct flash_descriptor supervisor_flash_desc; @@ -73,7 +74,7 @@ uint32_t supervisor_flash_get_block_count(void) { return INTERNAL_FLASH_PART1_NUM_BLOCKS; } -void supervisor_flash_flush(void) { +void port_internal_flash_flush(void) { } void supervisor_flash_release_cache(void) { diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 6b368e27b..92ef35680 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -32,6 +32,7 @@ // ASF 4 #include "atmel_start_pins.h" +#include "peripheral_clk_config.h" #include "hal/include/hal_delay.h" #include "hal/include/hal_flash.h" #include "hal/include/hal_gpio.h" @@ -134,12 +135,16 @@ static void save_usb_clock_calibration(void) { static void rtc_init(void) { #ifdef SAMD21 - _gclk_enable_channel(RTC_GCLK_ID, CONF_GCLK_RTC_SRC); + _gclk_enable_channel(RTC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK2_Val); + RTC->MODE0.CTRL.bit.SWRST = true; + while (RTC->MODE0.CTRL.bit.SWRST != 0) {} + + RTC->MODE0.CTRL.reg = RTC_MODE0_CTRL_ENABLE | + RTC_MODE0_CTRL_MODE_COUNT32 | + RTC_MODE0_CTRL_PRESCALER_DIV2; #endif #ifdef SAMD51 hri_mclk_set_APBAMASK_RTC_bit(MCLK); -#endif - RTC->MODE0.CTRLA.bit.SWRST = true; while (RTC->MODE0.SYNCBUSY.bit.SWRST != 0) {} @@ -147,6 +152,8 @@ static void rtc_init(void) { RTC_MODE0_CTRLA_MODE_COUNT32 | RTC_MODE0_CTRLA_PRESCALER_DIV2 | RTC_MODE0_CTRLA_COUNTSYNC; +#endif + RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_OVF; // Set all peripheral interrupt priorities to the lowest priority by default. @@ -384,6 +391,7 @@ uint32_t port_get_saved_word(void) { // TODO: Move this to an RTC backup register so we can preserve it when only the BACKUP power domain // is enabled. static volatile uint64_t overflowed_ticks = 0; +static volatile bool _ticks_enabled = false; void RTC_Handler(void) { uint32_t intflag = RTC->MODE0.INTFLAG.reg; @@ -392,20 +400,44 @@ void RTC_Handler(void) { // Our RTC is 32 bits and we're clocking it at 16.384khz which is 16 (2 ** 4) subticks per // tick. overflowed_ticks += (1L<< (32 - 4)); - + #ifdef SAMD51 } else if (intflag & RTC_MODE0_INTFLAG_PER2) { RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_PER2; // Do things common to all ports when the tick occurs supervisor_tick(); + #endif } else if (intflag & RTC_MODE0_INTFLAG_CMP0) { - RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0; + // Clear the interrupt because we may have hit a sleep and _ticks_enabled RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; + #ifdef SAMD21 + if (_ticks_enabled) { + // Do things common to all ports when the tick occurs. + supervisor_tick(); + // Check _ticks_enabled again because a tick handler may have turned it off. + if (_ticks_enabled) { + port_interrupt_after_ticks(1); + } + } + #endif + #ifdef SAMD51 + RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0; + #endif } } -uint64_t port_get_raw_ticks(uint8_t* subticks) { +static uint32_t _get_count(void) { + #ifdef SAMD51 while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT)) != 0) {} - uint32_t current_ticks = RTC->MODE0.COUNT.reg; + #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) { *subticks = (current_ticks % 16) * 2; } @@ -415,18 +447,29 @@ uint64_t port_get_raw_ticks(uint8_t* subticks) { // Enable 1/1024 second tick. void port_enable_tick(void) { + #ifdef SAMD51 // PER2 will generate an interrupt every 32 ticks of the source 32.768 clock. RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_PER2; + #endif + #ifdef SAMD21 + _ticks_enabled = true; + port_interrupt_after_ticks(1); + #endif } // Disable 1/1024 second tick. void port_disable_tick(void) { + #ifdef SAMD51 RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_PER2; + #endif + #ifdef SAMD21 + _ticks_enabled = false; + RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0; + #endif } void port_interrupt_after_ticks(uint32_t ticks) { - while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT)) != 0) {} - uint32_t current_ticks = RTC->MODE0.COUNT.reg; + uint32_t current_ticks = _get_count(); if (ticks > 1 << 28) { // We'll interrupt sooner with an overflow. return; @@ -437,11 +480,13 @@ void port_interrupt_after_ticks(uint32_t ticks) { } void port_sleep_until_interrupt(void) { + #ifdef SAMD51 // Clear the FPU interrupt because it can prevent us from sleeping. if (__get_FPSCR() & ~(0x9f)) { __set_FPSCR(__get_FPSCR() & ~(0x9f)); (void) __get_FPSCR(); } + #endif // Call wait for interrupt ourselves if the SD isn't enabled. __WFI(); } |
