fix up SAMD21 sleep
This commit is contained in:
parent
4297ae2d0b
commit
d9e68156b2
@ -42,7 +42,6 @@
|
|||||||
#include "samd/clocks.h"
|
#include "samd/clocks.h"
|
||||||
#include "samd/pins.h"
|
#include "samd/pins.h"
|
||||||
|
|
||||||
#include "tick.h"
|
|
||||||
#include "adafruit_ptc.h"
|
#include "adafruit_ptc.h"
|
||||||
|
|
||||||
bool touch_enabled = false;
|
bool touch_enabled = false;
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit df39529b42fbc43db3c9b5724dfb2d6c562e8489
|
Subproject commit bfbc88fd6b2e2bb8f5e88836c0ba46eb80f97577
|
@ -41,6 +41,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "hal/include/hal_flash.h"
|
#include "hal/include/hal_flash.h"
|
||||||
|
|
||||||
|
#include "supervisor/flash.h"
|
||||||
#include "supervisor/shared/rgb_led_status.h"
|
#include "supervisor/shared/rgb_led_status.h"
|
||||||
|
|
||||||
static struct flash_descriptor supervisor_flash_desc;
|
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;
|
return INTERNAL_FLASH_PART1_NUM_BLOCKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void supervisor_flash_flush(void) {
|
void port_internal_flash_flush(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void supervisor_flash_release_cache(void) {
|
void supervisor_flash_release_cache(void) {
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
// ASF 4
|
// ASF 4
|
||||||
#include "atmel_start_pins.h"
|
#include "atmel_start_pins.h"
|
||||||
|
#include "peripheral_clk_config.h"
|
||||||
#include "hal/include/hal_delay.h"
|
#include "hal/include/hal_delay.h"
|
||||||
#include "hal/include/hal_flash.h"
|
#include "hal/include/hal_flash.h"
|
||||||
#include "hal/include/hal_gpio.h"
|
#include "hal/include/hal_gpio.h"
|
||||||
@ -134,12 +135,16 @@ static void save_usb_clock_calibration(void) {
|
|||||||
|
|
||||||
static void rtc_init(void) {
|
static void rtc_init(void) {
|
||||||
#ifdef SAMD21
|
#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
|
#endif
|
||||||
#ifdef SAMD51
|
#ifdef SAMD51
|
||||||
hri_mclk_set_APBAMASK_RTC_bit(MCLK);
|
hri_mclk_set_APBAMASK_RTC_bit(MCLK);
|
||||||
#endif
|
|
||||||
|
|
||||||
RTC->MODE0.CTRLA.bit.SWRST = true;
|
RTC->MODE0.CTRLA.bit.SWRST = true;
|
||||||
while (RTC->MODE0.SYNCBUSY.bit.SWRST != 0) {}
|
while (RTC->MODE0.SYNCBUSY.bit.SWRST != 0) {}
|
||||||
|
|
||||||
@ -147,6 +152,8 @@ static void rtc_init(void) {
|
|||||||
RTC_MODE0_CTRLA_MODE_COUNT32 |
|
RTC_MODE0_CTRLA_MODE_COUNT32 |
|
||||||
RTC_MODE0_CTRLA_PRESCALER_DIV2 |
|
RTC_MODE0_CTRLA_PRESCALER_DIV2 |
|
||||||
RTC_MODE0_CTRLA_COUNTSYNC;
|
RTC_MODE0_CTRLA_COUNTSYNC;
|
||||||
|
#endif
|
||||||
|
|
||||||
RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_OVF;
|
RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_OVF;
|
||||||
|
|
||||||
// Set all peripheral interrupt priorities to the lowest priority by default.
|
// 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
|
// TODO: Move this to an RTC backup register so we can preserve it when only the BACKUP power domain
|
||||||
// is enabled.
|
// is enabled.
|
||||||
static volatile uint64_t overflowed_ticks = 0;
|
static volatile uint64_t overflowed_ticks = 0;
|
||||||
|
static volatile bool _ticks_enabled = false;
|
||||||
|
|
||||||
void RTC_Handler(void) {
|
void RTC_Handler(void) {
|
||||||
uint32_t intflag = RTC->MODE0.INTFLAG.reg;
|
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
|
// Our RTC is 32 bits and we're clocking it at 16.384khz which is 16 (2 ** 4) subticks per
|
||||||
// tick.
|
// tick.
|
||||||
overflowed_ticks += (1L<< (32 - 4));
|
overflowed_ticks += (1L<< (32 - 4));
|
||||||
|
#ifdef SAMD51
|
||||||
} else if (intflag & RTC_MODE0_INTFLAG_PER2) {
|
} else if (intflag & RTC_MODE0_INTFLAG_PER2) {
|
||||||
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_PER2;
|
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_PER2;
|
||||||
// Do things common to all ports when the tick occurs
|
// Do things common to all ports when the tick occurs
|
||||||
supervisor_tick();
|
supervisor_tick();
|
||||||
|
#endif
|
||||||
} else if (intflag & RTC_MODE0_INTFLAG_CMP0) {
|
} 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;
|
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) {}
|
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) {
|
if (subticks != NULL) {
|
||||||
*subticks = (current_ticks % 16) * 2;
|
*subticks = (current_ticks % 16) * 2;
|
||||||
}
|
}
|
||||||
@ -415,18 +447,29 @@ uint64_t port_get_raw_ticks(uint8_t* subticks) {
|
|||||||
|
|
||||||
// Enable 1/1024 second tick.
|
// Enable 1/1024 second tick.
|
||||||
void port_enable_tick(void) {
|
void port_enable_tick(void) {
|
||||||
|
#ifdef SAMD51
|
||||||
// PER2 will generate an interrupt every 32 ticks of the source 32.768 clock.
|
// PER2 will generate an interrupt every 32 ticks of the source 32.768 clock.
|
||||||
RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_PER2;
|
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.
|
// Disable 1/1024 second tick.
|
||||||
void port_disable_tick(void) {
|
void port_disable_tick(void) {
|
||||||
|
#ifdef SAMD51
|
||||||
RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_PER2;
|
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) {
|
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 = _get_count();
|
||||||
uint32_t current_ticks = RTC->MODE0.COUNT.reg;
|
|
||||||
if (ticks > 1 << 28) {
|
if (ticks > 1 << 28) {
|
||||||
// We'll interrupt sooner with an overflow.
|
// We'll interrupt sooner with an overflow.
|
||||||
return;
|
return;
|
||||||
@ -437,11 +480,13 @@ void port_interrupt_after_ticks(uint32_t ticks) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void port_sleep_until_interrupt(void) {
|
void port_sleep_until_interrupt(void) {
|
||||||
|
#ifdef SAMD51
|
||||||
// Clear the FPU interrupt because it can prevent us from sleeping.
|
// Clear the FPU interrupt because it can prevent us from sleeping.
|
||||||
if (__get_FPSCR() & ~(0x9f)) {
|
if (__get_FPSCR() & ~(0x9f)) {
|
||||||
__set_FPSCR(__get_FPSCR() & ~(0x9f));
|
__set_FPSCR(__get_FPSCR() & ~(0x9f));
|
||||||
(void) __get_FPSCR();
|
(void) __get_FPSCR();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// Call wait for interrupt ourselves if the SD isn't enabled.
|
// Call wait for interrupt ourselves if the SD isn't enabled.
|
||||||
__WFI();
|
__WFI();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user