Merge pull request #3532 from tannewt/samd21_autoreload
Fix autoreload on SAMD21
This commit is contained in:
commit
c7d87cea62
@ -430,6 +430,33 @@ uint32_t port_get_saved_word(void) {
|
|||||||
static volatile uint64_t overflowed_ticks = 0;
|
static volatile uint64_t overflowed_ticks = 0;
|
||||||
static volatile bool _ticks_enabled = false;
|
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) {
|
void RTC_Handler(void) {
|
||||||
uint32_t intflag = RTC->MODE0.INTFLAG.reg;
|
uint32_t intflag = RTC->MODE0.INTFLAG.reg;
|
||||||
if (intflag & RTC_MODE0_INTFLAG_OVF) {
|
if (intflag & RTC_MODE0_INTFLAG_OVF) {
|
||||||
@ -452,7 +479,7 @@ void RTC_Handler(void) {
|
|||||||
supervisor_tick();
|
supervisor_tick();
|
||||||
// Check _ticks_enabled again because a tick handler may have turned it off.
|
// Check _ticks_enabled again because a tick handler may have turned it off.
|
||||||
if (_ticks_enabled) {
|
if (_ticks_enabled) {
|
||||||
port_interrupt_after_ticks(1);
|
_port_interrupt_after_ticks(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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) {
|
uint64_t port_get_raw_ticks(uint8_t* subticks) {
|
||||||
uint32_t current_ticks = _get_count();
|
uint32_t current_ticks = _get_count();
|
||||||
if (subticks != NULL) {
|
if (subticks != NULL) {
|
||||||
@ -490,7 +506,7 @@ void port_enable_tick(void) {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef SAMD21
|
#ifdef SAMD21
|
||||||
_ticks_enabled = true;
|
_ticks_enabled = true;
|
||||||
port_interrupt_after_ticks(1);
|
_port_interrupt_after_ticks(1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,20 +521,14 @@ void port_disable_tick(void) {
|
|||||||
#endif
|
#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) {
|
void port_interrupt_after_ticks(uint32_t ticks) {
|
||||||
uint32_t current_ticks = _get_count();
|
if (_ticks_enabled) {
|
||||||
if (ticks > 1 << 28) {
|
|
||||||
// We'll interrupt sooner with an overflow.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef SAMD21
|
_port_interrupt_after_ticks(ticks);
|
||||||
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 port_sleep_until_interrupt(void) {
|
void port_sleep_until_interrupt(void) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user