Skip to content

Commit d9e6815

Browse files
committed
fix up SAMD21 sleep
1 parent 4297ae2 commit d9e6815

4 files changed

Lines changed: 57 additions & 12 deletions

File tree

ports/atmel-samd/common-hal/touchio/TouchIn.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
#include "samd/clocks.h"
4343
#include "samd/pins.h"
4444

45-
#include "tick.h"
4645
#include "adafruit_ptc.h"
4746

4847
bool touch_enabled = false;

ports/atmel-samd/peripherals

ports/atmel-samd/supervisor/internal_flash.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#endif
4242
#include "hal/include/hal_flash.h"
4343

44+
#include "supervisor/flash.h"
4445
#include "supervisor/shared/rgb_led_status.h"
4546

4647
static struct flash_descriptor supervisor_flash_desc;
@@ -73,7 +74,7 @@ uint32_t supervisor_flash_get_block_count(void) {
7374
return INTERNAL_FLASH_PART1_NUM_BLOCKS;
7475
}
7576

76-
void supervisor_flash_flush(void) {
77+
void port_internal_flash_flush(void) {
7778
}
7879

7980
void supervisor_flash_release_cache(void) {

ports/atmel-samd/supervisor/port.c

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
// ASF 4
3434
#include "atmel_start_pins.h"
35+
#include "peripheral_clk_config.h"
3536
#include "hal/include/hal_delay.h"
3637
#include "hal/include/hal_flash.h"
3738
#include "hal/include/hal_gpio.h"
@@ -134,19 +135,25 @@ static void save_usb_clock_calibration(void) {
134135

135136
static void rtc_init(void) {
136137
#ifdef SAMD21
137-
_gclk_enable_channel(RTC_GCLK_ID, CONF_GCLK_RTC_SRC);
138+
_gclk_enable_channel(RTC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK2_Val);
139+
RTC->MODE0.CTRL.bit.SWRST = true;
140+
while (RTC->MODE0.CTRL.bit.SWRST != 0) {}
141+
142+
RTC->MODE0.CTRL.reg = RTC_MODE0_CTRL_ENABLE |
143+
RTC_MODE0_CTRL_MODE_COUNT32 |
144+
RTC_MODE0_CTRL_PRESCALER_DIV2;
138145
#endif
139146
#ifdef SAMD51
140147
hri_mclk_set_APBAMASK_RTC_bit(MCLK);
141-
#endif
142-
143148
RTC->MODE0.CTRLA.bit.SWRST = true;
144149
while (RTC->MODE0.SYNCBUSY.bit.SWRST != 0) {}
145150

146151
RTC->MODE0.CTRLA.reg = RTC_MODE0_CTRLA_ENABLE |
147152
RTC_MODE0_CTRLA_MODE_COUNT32 |
148153
RTC_MODE0_CTRLA_PRESCALER_DIV2 |
149154
RTC_MODE0_CTRLA_COUNTSYNC;
155+
#endif
156+
150157
RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_OVF;
151158

152159
// Set all peripheral interrupt priorities to the lowest priority by default.
@@ -384,6 +391,7 @@ uint32_t port_get_saved_word(void) {
384391
// TODO: Move this to an RTC backup register so we can preserve it when only the BACKUP power domain
385392
// is enabled.
386393
static volatile uint64_t overflowed_ticks = 0;
394+
static volatile bool _ticks_enabled = false;
387395

388396
void RTC_Handler(void) {
389397
uint32_t intflag = RTC->MODE0.INTFLAG.reg;
@@ -392,20 +400,44 @@ void RTC_Handler(void) {
392400
// Our RTC is 32 bits and we're clocking it at 16.384khz which is 16 (2 ** 4) subticks per
393401
// tick.
394402
overflowed_ticks += (1L<< (32 - 4));
395-
403+
#ifdef SAMD51
396404
} else if (intflag & RTC_MODE0_INTFLAG_PER2) {
397405
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_PER2;
398406
// Do things common to all ports when the tick occurs
399407
supervisor_tick();
408+
#endif
400409
} else if (intflag & RTC_MODE0_INTFLAG_CMP0) {
401-
RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
410+
// Clear the interrupt because we may have hit a sleep and _ticks_enabled
402411
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
412+
#ifdef SAMD21
413+
if (_ticks_enabled) {
414+
// Do things common to all ports when the tick occurs.
415+
supervisor_tick();
416+
// Check _ticks_enabled again because a tick handler may have turned it off.
417+
if (_ticks_enabled) {
418+
port_interrupt_after_ticks(1);
419+
}
420+
}
421+
#endif
422+
#ifdef SAMD51
423+
RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
424+
#endif
403425
}
404426
}
405427

406-
uint64_t port_get_raw_ticks(uint8_t* subticks) {
428+
static uint32_t _get_count(void) {
429+
#ifdef SAMD51
407430
while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT)) != 0) {}
408-
uint32_t current_ticks = RTC->MODE0.COUNT.reg;
431+
#endif
432+
#ifdef SAMD21
433+
while (RTC->MODE0.STATUS.bit.SYNCBUSY != 0) {}
434+
#endif
435+
436+
return RTC->MODE0.COUNT.reg;
437+
}
438+
439+
uint64_t port_get_raw_ticks(uint8_t* subticks) {
440+
uint32_t current_ticks = _get_count();
409441
if (subticks != NULL) {
410442
*subticks = (current_ticks % 16) * 2;
411443
}
@@ -415,18 +447,29 @@ uint64_t port_get_raw_ticks(uint8_t* subticks) {
415447

416448
// Enable 1/1024 second tick.
417449
void port_enable_tick(void) {
450+
#ifdef SAMD51
418451
// PER2 will generate an interrupt every 32 ticks of the source 32.768 clock.
419452
RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_PER2;
453+
#endif
454+
#ifdef SAMD21
455+
_ticks_enabled = true;
456+
port_interrupt_after_ticks(1);
457+
#endif
420458
}
421459

422460
// Disable 1/1024 second tick.
423461
void port_disable_tick(void) {
462+
#ifdef SAMD51
424463
RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_PER2;
464+
#endif
465+
#ifdef SAMD21
466+
_ticks_enabled = false;
467+
RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
468+
#endif
425469
}
426470

427471
void port_interrupt_after_ticks(uint32_t ticks) {
428-
while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT)) != 0) {}
429-
uint32_t current_ticks = RTC->MODE0.COUNT.reg;
472+
uint32_t current_ticks = _get_count();
430473
if (ticks > 1 << 28) {
431474
// We'll interrupt sooner with an overflow.
432475
return;
@@ -437,11 +480,13 @@ void port_interrupt_after_ticks(uint32_t ticks) {
437480
}
438481

439482
void port_sleep_until_interrupt(void) {
483+
#ifdef SAMD51
440484
// Clear the FPU interrupt because it can prevent us from sleeping.
441485
if (__get_FPSCR() & ~(0x9f)) {
442486
__set_FPSCR(__get_FPSCR() & ~(0x9f));
443487
(void) __get_FPSCR();
444488
}
489+
#endif
445490
// Call wait for interrupt ourselves if the SD isn't enabled.
446491
__WFI();
447492
}

0 commit comments

Comments
 (0)