defragster
Senior Member+
What I not understand is the following:
I tell SNVS to wake-up the processor, say in 1 minute.
I expect that alarm ISR is called after 1 minute, but MCU is not running, therefore alarm ISR can not run.
Also, power off means all RAM (including alarm ISR code) is lost.
So what the purpose of ISR?
commenting attachInterruptVector seems not work (no wake-up). I.e. the default ISR that has no "SNVS_LPSR |= 1;" and therefore seems not to work.
It seems that the alarm interrupt is called immediately after being enabled, but the wake-up is at the indicated time.
Edit, as '+' member could you please edit the title of this thread and remove the disturbing 'o'?
+Not: Thread titles are set in stone as they are the root of any link I suppose … Sorry the 'o' stays
I wasn't sure about the _isr() - it fires immediately on/at EXIT? Maybe that is the MCU giving an ACK that the timer has been activated? Firing going into Sleep means the CPU and RAM are still active - but it is about to sleep.
Putting more BLINK code in _isr() - the ISR does not fire the first time after programming - but it does each time after that? And it fires before Sleep not on Wake.
Also until the rtc_isr() exits - when called after the first time - the MCU does not enter sleep.
Here is edited code - will Sleep when any USB char is sent - not on a timer. Altered blink(#) calls for flash:
Code:
#include "core_pins.h"
#include "TimeLib.h"
/******************* Seting Alarm ***************/
#define SNVS_LPCR_LPTA_EN_MASK (0x2U)
void rtc_stopAlarm()
{
SNVS_LPSR |= 1;
// disable alarm
SNVS_LPCR &= ~SNVS_LPCR_LPTA_EN_MASK;
while (SNVS_LPCR & SNVS_LPCR_LPTA_EN_MASK);
// clear alarm value
SNVS_LPTAR = 0;
while (SNVS_LPTAR != 0);
}
void rtc_isr(void)
{
digitalWriteFast(13, 1);
delayMicroseconds(2000000); // to let USB write last line
for ( int ic = 0; ic < 12; ic++ ) {
blink( 40 );
delay(50); // to let USB write last line
}
SNVS_LPSR |= 1;
Serial.println("Alarm"); Serial.flush();// only to tell if ISR is called
asm volatile ("DSB");
}
void rtc_setAlarm(uint32_t alarmSeconds, uint32_t prio = 13)
{ uint32_t tmp = SNVS_LPCR; //save control register
/* disable SRTC alarm interrupt */
rtc_stopAlarm();
SNVS_LPTAR = alarmSeconds;
while (SNVS_LPTAR != alarmSeconds);
attachInterruptVector(IRQ_SNVS_IRQ, rtc_isr);
NVIC_SET_PRIORITY(IRQ_SNVS_IRQ, prio * 16); // 8 is normal priority
NVIC_DISABLE_IRQ(IRQ_SNVS_IRQ);
NVIC_ENABLE_IRQ(IRQ_SNVS_IRQ);
SNVS_LPCR = tmp | SNVS_LPCR_LPTA_EN_MASK; // restore control register and set alarm
while (!(SNVS_LPCR & SNVS_LPCR_LPTA_EN_MASK));
}
uint32_t rtc_getAlarm()
{
return SNVS_LPTAR;
}
void doShutdown(void)
{
SNVS_LPCR |= (1 << 6) ; // turn off power
}
void setWakeupCallandSleep(uint32_t nsec)
{
uint32_t to = now();
rtc_setAlarm(to + nsec, 4);
doShutdown();
while (1) asm("wfi");
}
uint32_t blink( uint32_t tWait)
{ static uint32_t tx0;
if (millis() > tx0 + tWait)
{ digitalWriteFast(13, !digitalReadFast(13));
tx0 = millis();
Serial.println("blink");
return 1;
}
return 0;
}
void setup() {
Serial.begin(9600);
while (!Serial);
// set the Time library to use Teensy 3.0's RTC to keep time
setSyncProvider((getExternalTime)Teensy3Clock.get);
delay(100);
if (timeStatus() != timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
//
Serial.println("Start");
rtc_stopAlarm();
pinMode(13, OUTPUT);
}
void loop() {
static uint32_t ic = 0;
ic += blink( 1000 );
if (Serial.available())
//if (ic >= 20)
{ Serial.println("End"); Serial.flush();
for ( ic = 0; ic < 12; ic++ ) {
blink( 40 );
delay(50); // to let USB write last line
}
digitalWriteFast(13, 0);
delay(400); // to let USB write last line
setWakeupCallandSleep(2);
}
}