Hello,
I'm trying to get the Arduino MKR 1010 in a deep sleep state and wake it up every minute with a timer (TC) interrupt. I've been trying for so long, but I can't get it.
In the code, which I enclose, the time cofiguration is 10s.
Hope you can help me,
Martin.
bool valor=LOW;
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN,OUTPUT);
GCLK_Config();
TimerConfig();
EventConfig();
InterruptConfig();
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // Put the SAMD21 in deep sleep upon executing the __WFI() function
NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_SLEEPPRM_DISABLED;
__DSB();
}
void loop() {
while(!Serial);
Serial.println("LOOP");
// delay(5000);
// __WFI();
// Serial.println("Abajo");
}
void GCLK_Config(){
REG_SYSCTRL_XOSC32K = SYSCTRL_XOSC32K_ONDEMAND | // Enble one demand mode
SYSCTRL_XOSC32K_RUNSTDBY | // Enable run-on-standby mode
SYSCTRL_XOSC32K_EN32K | // Enable the crystal oscillator IO pads
SYSCTRL_XOSC32K_XTALEN | // Enable the crystal oscillator
SYSCTRL_XOSC32K_STARTUP(6) | // Set the crystal start-up time
SYSCTRL_XOSC32K_ENABLE; // Enable the oscillator
REG_GCLK_GENDIV = GCLK_GENDIV_ID(4) | // GCLK0 como fuente del CLK genérico.
GCLK_GENDIV_DIV(1); // Factor de division del GCLK.
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization __DSB();
REG_GCLK_GENCTRL = GCLK_GENCTRL_ID(4) | // Seleccionamos GCLK0.
GCLK_GENCTRL_SRC_XOSC32K | //La fuente del CLK es el oscilador.
GCLK_GENCTRL_GENEN | //Habilitación del GCLK
GCLK_GENCTRL_RUNSTDBY; //Activo durante el bajo consumo.
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID_TC4_TC5 | //GCLK alimenta a TCC2 y TC3
GCLK_CLKCTRL_GEN_GCLK4 | //Seleccionamos GCLK0
GCLK_CLKCTRL_CLKEN; //Habilitación
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4
GCLK_CLKCTRL_ID_EVSYS_0 | // Feed the Event System channel 0
GCLK_CLKCTRL_CLKEN; // Enable GCLK4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
}
void InterruptConfig(){
NVIC_SetPriority(EVSYS_IRQn, 0); // Set the Nested Vector Interrupt Controller (NVIC) priority for TC4 to 0 (highest)
NVIC_EnableIRQ(EVSYS_IRQn); // Connect TC4 to Nested Vector Interrupt Controller (NVIC)
EVSYS->INTENSET.reg = EVSYS_INTENSET_EVD0; // Set Event System interrupt on event detection
}
void TimerConfig(){
REG_PM_APBCMASK |= PM_APBCMASK_TC4; // TC bus clock (PM_component (aparece como "TC4_"))
REG_TC4_COUNT16_CC0=0x13FF; //0x77FF=(30719+1)/512=60s
REG_TC4_INTFLAG |= TC_INTFLAG_OVF; //Limpiamos el flag de overflow
REG_TC4_INTENSET = TC_INTENSET_OVF; //Habilitación de la interrupción por overflow
REG_TC4_CTRLA |= TC_CTRLA_PRESCALER_DIV64 | //32768/64=512Hz
TC_CTRLA_WAVEGEN_MFRQ | //Match Frecuency Generation
TC_CTRLA_RUNSTDBY | //Activo en modo bajo consumo
TC_CTRLA_ENABLE; //Habilitacion del timer
__DSB();
}
void EventConfig(){
REG_PM_APBCMASK |= PM_APBCMASK_EVSYS; // Switch on the event system peripheral
REG_EVSYS_USER = EVSYS_USER_CHANNEL(1) | //Ningún canal (por ahora)
EVSYS_USER_USER(0x13); //Seleccionamos el TC4.
REG_EVSYS_CHANNEL = EVSYS_CHANNEL_CHANNEL(0) | //Canal 0
EVSYS_CHANNEL_PATH_SYNCHRONOUS | //Comparten GCLK
//EVSYS_CHANNEL_PATH_RESYNCHRONIZED | //No comparten GCLK
EVSYS_CHANNEL_EDGSEL_RISING_EDGE |
//EVSYS_CHANNEL_EVGEN(0x37); //El generador del evento es un match en TC4.
EVSYS_CHANNEL_EVGEN(0x36); //El generador es un overflow en TC4.
}
void EVSYS_Handler()
{
valor=!valor;
digitalWrite(LED_BUILTIN,valor);
REG_TC4_INTFLAG |= TC_INTFLAG_OVF; // Borrar flag de interrupcion por overflow
EVSYS->INTFLAG.bit.EVD0 = 1; // Borrar flag interrupcion
//__WFI();
}
Registros.ino (4.66 KB)