Hi Martin,
I've been trying to get the RTC periodic events to work but have encountered a problem that has slowed me down. I am trying to configure the EVSYS peripheral so that the RTC periodic event 7 (1 Hz) generates an interrupt using EVSYS channel 0.
I have added the following code snippet to the RTCZero begin() method:
PM->APBCMASK.reg |= PM_APBCMASK_EVSYS; // turn on the event system peripheral
NVIC_EnableIRQ(EVSYS_IRQn); // enable EVSYS interrupt
NVIC_SetPriority(EVSYS_IRQn, 0x00);
EVSYS->USER.reg = EVSYS_USER_CHANNEL(0x01) | EVSYS_USER_USER(EVSYS_ID_USER_DMAC_CH_0);
EVSYS->CHANNEL.reg = EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT |
EVSYS_CHANNEL_PATH_ASYNCHRONOUS |
EVSYS_CHANNEL_EVGEN(EVSYS_ID_GEN_RTC_PER_7) | // Period = 2^(7+3)
EVSYS_CHANNEL_CHANNEL(0); // Event Channel 0
EVSYS->INTENSET.reg |= EVSYS_INTENSET_EVD0; // enable interrupt for channel 0
while (RTCisSyncing())
;
I also augmented the configureClock() method to connect GCLK2 to the Event System:
// Feed GCLK2 to Event System Channel 0
GCLK->CLKCTRL.reg = (uint32_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK2 | GCLK_CLKCTRL_ID_EVSYS_0);
while (GCLK->STATUS.bit.SYNCBUSY)
;
I added some functions to configure the interrupt callback:
void EVSYS_Handler(void)
{
digitalWrite( 2, HIGH );
digitalWrite( 2, LOW );
if (EVSYS_callBack != NULL) {
EVSYS_callBack();
}
EVSYS->INTFLAG.reg = EVSYS_INTFLAG_EVD0; // must clear interrupt flag at end of handler
}
void RTCZero::attachPeriodicInterrupt(voidFuncPtr callback)
{
EVSYS_callBack = callback;
}
void RTCZero::detachPeriodicInterrupt()
{
EVSYS_callBack = NULL;
}
And created a callback which just toggles a pin a couple times:
void rtcPeriodicEvent() {
// EVSYS periodic event interrupt callback
// rtcTick += RTC_PERIODIC_EVENT_TIMEOUT;
ISB_DEBUG( digitalWrite(HOST_INT1, HIGH); ); // DEBUG ONLY: use pin to trigger scope when MCU wakes up
ISB_DEBUG( digitalWrite(HOST_INT1, LOW); ); // DEBUG ONLY: use pin to trigger scope when MCU wakes up
ISB_DEBUG( digitalWrite(HOST_INT1, HIGH); ); // DEBUG ONLY: use pin to trigger scope when MCU wakes up
ISB_DEBUG( digitalWrite(HOST_INT1, LOW); ); // DEBUG ONLY: use pin to trigger scope when MCU wakes up
}
The problem is that when I attempt to enable the periodic event as follows:
RTC->MODE2.EVCTRL.reg |= _periodicEvent;
where _periodicEvent = RTC_MODE2_EVCTRL_PEREO7;
The MCU appears to freeze and eventually the watchdog times out and reboots. I checked the datasheet and I think I am initializing the event system correctly but something must be wrong. I initially attempted to configure channel 0 with no user (instead of DMAC_CH_0) and that configuration exhibits the same problem. I tried using a different event channel (channel 4 instead of channel 0) and this exhibits the same behaviour.