as a noob I don't really master all the setting this code does (I copied it from the tubes) but I stumbled onto something strange:
0- the code simply generates a 1 Hz software interrupt using the RTC
1- the same code behave differently on a trinket M0 and on a feather M0 Express
2a- it stalls on a feather M0 Express but not right away (after flashing, it is always OK)
2b- you have to unplug and replug it to reproduce the problem
3- the same code is OK on a trinket M0 and never stall when power cycling the board
4- once stalled, the feather will always stall at the first SYNCBUSY wait, even when reflashed
5- to un-stall the feather, I reflash it twice with the Arduino IDE Board set as a Trinket M0 and then as a Feather M0 Express
my running set up:
Adafruit Feather M0 Express (SN: 8B80728B50533830332E3120FF162525)
Arduino IDE 1.8.14 on Ubuntu 20.04.3, Adafruit SAMD Boards 1.6.7 installed
Thanks for any help!
PS: I need the 1 Hz RTC event to replace the GPS PPS when signal reception is bad.
Code: Select all
// Set-up RTC interrupt to fire every second (1Hz) in clock/calendar mode (Mode 2)
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("\n\nentered setup()");
// Configure clock source and clock generators (gclk.h)------------------------
GCLK->GENDIV.reg = GCLK_GENDIV_ID(4) | GCLK_GENDIV_DIV(4);
while (GCLK->STATUS.bit.SYNCBUSY);
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID(4) | GCLK_GENCTRL_SRC_OSC32K |
GCLK_GENCTRL_IDC | GCLK_GENCTRL_RUNSTDBY |
GCLK_GENCTRL_DIVSEL | GCLK_GENCTRL_GENEN;
while (GCLK->STATUS.bit.SYNCBUSY);
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN_GCLK4 | GCLK_CLKCTRL_ID_RTC |
GCLK_CLKCTRL_CLKEN;
while (GCLK->STATUS.bit.SYNCBUSY);
// configure RTC
RTC->MODE2.CTRL.reg |= RTC_MODE2_CTRL_PRESCALER_DIV1024 |
RTC_MODE2_CTRL_MODE_CLOCK;
RTC->MODE2.Mode2Alarm[0].ALARM.bit.SECOND = RTC_MODE2_ALARM_SECOND(0);
Serial.println("just before while (RTC->MODE2.STATUS.bit.SYNCBUSY);");---------
while (RTC->MODE2.STATUS.bit.SYNCBUSY); // <--- it stalls here
// if a Feather M0 Express is power cycled...
// but not a Trinket M0 !
// once the feather is stalled, reflashing it changes nothing.
// to un-stall the feather, you have to flash it as a TrinketM0
Serial.println("just after while (RTC->MODE2.STATUS.bit.SYNCBUSY);");-----------
RTC->MODE2.Mode2Alarm[0].MASK.bit.SEL = RTC_MODE2_MASK_SEL_SS;
while (RTC->MODE2.STATUS.bit.SYNCBUSY);
// Configure RTC interrupts
NVIC_SetPriority(RTC_IRQn, 0);
NVIC_EnableIRQ(RTC_IRQn);
RTC->MODE2.INTENSET.reg = RTC_MODE2_INTENSET_ALARM0;
// Enable RTC
RTC->MODE2.CLOCK.reg = 0x0000000;
while (RTC->MODE2.STATUS.bit.SYNCBUSY);
RTC->MODE2.CTRL.reg |= RTC_MODE2_CTRL_ENABLE;
while (RTC->MODE2.STATUS.bit.SYNCBUSY);
Serial.println("Setup complete...");
}
void loop() {}
void RTC_Handler(void)
{
if (RTC->MODE2.INTFLAG.bit.ALARM0 && RTC->MODE2.INTENSET.bit.ALARM0)
{
Serial.print(F("RTC Handler, "));
RTC->MODE2.READREQ.reg = RTC_READREQ_RREQ;
while (RTC->MODE2.STATUS.bit.SYNCBUSY);
uint8_t min = RTC->MODE2.CLOCK.bit.MINUTE;
uint8_t sec = RTC->MODE2.CLOCK.bit.SECOND;
Serial.print(min); Serial.print("m "); Serial.print(sec); Serial.println("s");
RTC->MODE2.INTFLAG.reg = RTC_MODE2_INTFLAG_ALARM0;
RTC->MODE2.Mode2Alarm[0].ALARM.bit.SECOND = (RTC->MODE2.Mode2Alarm[0].ALARM.bit.SECOND + 1) % 60;
}
}