Feather m0 (SAMD) sleep and interrupt
-
Hi,
I've been trying everything I know of to get a feather m0 wake up by interrupt after deep sleep but I can't get it working with the mysensors lib.
if I remove all mysensors related code sleep and wakeup works just fine :unamused:
Any help or tip appreciated!Here's the code:
#define MY_DEBUG #define MY_RADIO_RFM69 #define TIME_TO_SLEEP 299 #define Battery_HIGH 4.2 #define Battery_LOW 3.2 #define MY_IS_RFM69HW #define MY_RFM69_FREQUENCY RFM69_433MHZ #define MY_RFM69_NEW_DRIVER #define MY_DEFAULT_ERR_LED_PIN 13 #define MY_RFM69_RST_PIN 4 #define MY_RFM69_IRQ_PIN 3 #define MY_RFM69_CS_PIN 8 #define MY_NODE_ID 11 #define MY_SIGNAL_REPORT_ENABLED #define MY_TRANSPORT_WAIT_READY_MS 15000 #include <MySensors.h> #define REEDSWITCHPIN 6 volatile bool SLEEP_FLAG = true; // Use sleeproutines or not bool debug = true; int bootCycles = 0; String wakeupReason = "none"; void setup() { pinMode(REEDSWITCHPIN, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(REEDSWITCHPIN), EIC_ISR, FALLING); delay(100); sleepSetup(); } void presentation() { } void loop() { delay(5000); Serial.println("Going to sleep in 60 seconds..."); delay(60000); if (debug) Serial.print("REEDSWITCHPIN State: "); if (debug) Serial.println(REEDSWITCHPIN); sleepRoutine(); } void sleepRoutine() { PORT->Group[g_APinDescription[LED_BUILTIN].ulPort].OUTCLR.reg = (uint32_t)(1<<g_APinDescription[LED_BUILTIN].ulPin); // set pin mode to low transportDisable(); // Disable rfm69 __DSB(); if (debug) Serial.println("ZzZ (WFI)"); USBDevice.detach(); delay(5000); __WFI(); // Sleep delay(1000); PORT->Group[g_APinDescription[LED_BUILTIN].ulPort].OUTTGL.reg = (uint32_t)(1<<g_APinDescription[LED_BUILTIN].ulPin); // toggle output of built-in LED pin USBDevice.attach(); delay(10000); if (debug) Serial.println("Out of ZzZ (WFI)"); //transportReInitialise(); // Enable rfm69 delay(100); } void EIC_ISR(void) { //SLEEP_FLAG ^= true; // toggle SLEEP_FLAG by XORing it against true wakeupReason = "INTERRUPT"; } void sleepSetup() { SYSCTRL->XOSC32K.reg |= (SYSCTRL_XOSC32K_RUNSTDBY | SYSCTRL_XOSC32K_ONDEMAND); // set external 32k oscillator to run when idle or sleep mode is chosen REG_GCLK_CLKCTRL |= GCLK_CLKCTRL_ID(GCM_EIC) | // generic clock multiplexer id for the external interrupt controller GCLK_CLKCTRL_GEN_GCLK1 | // generic clock 1 which is xosc32k GCLK_CLKCTRL_CLKEN; // enable it while (GCLK->STATUS.bit.SYNCBUSY); // write protected, wait for sync EIC->WAKEUP.reg |= EIC_WAKEUP_WAKEUPEN4; // Set External Interrupt Controller to use channel 4 (pin 6) PM->SLEEP.reg |= PM_SLEEP_IDLE_CPU; // Enable Idle0 mode - sleep CPU clock only SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // Enable Standby or "deep sleep" mode if (debug) Serial.println("EO sleepsetup"); } -
Hi,
I've been trying everything I know of to get a feather m0 wake up by interrupt after deep sleep but I can't get it working with the mysensors lib.
if I remove all mysensors related code sleep and wakeup works just fine :unamused:
Any help or tip appreciated!Here's the code:
#define MY_DEBUG #define MY_RADIO_RFM69 #define TIME_TO_SLEEP 299 #define Battery_HIGH 4.2 #define Battery_LOW 3.2 #define MY_IS_RFM69HW #define MY_RFM69_FREQUENCY RFM69_433MHZ #define MY_RFM69_NEW_DRIVER #define MY_DEFAULT_ERR_LED_PIN 13 #define MY_RFM69_RST_PIN 4 #define MY_RFM69_IRQ_PIN 3 #define MY_RFM69_CS_PIN 8 #define MY_NODE_ID 11 #define MY_SIGNAL_REPORT_ENABLED #define MY_TRANSPORT_WAIT_READY_MS 15000 #include <MySensors.h> #define REEDSWITCHPIN 6 volatile bool SLEEP_FLAG = true; // Use sleeproutines or not bool debug = true; int bootCycles = 0; String wakeupReason = "none"; void setup() { pinMode(REEDSWITCHPIN, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(REEDSWITCHPIN), EIC_ISR, FALLING); delay(100); sleepSetup(); } void presentation() { } void loop() { delay(5000); Serial.println("Going to sleep in 60 seconds..."); delay(60000); if (debug) Serial.print("REEDSWITCHPIN State: "); if (debug) Serial.println(REEDSWITCHPIN); sleepRoutine(); } void sleepRoutine() { PORT->Group[g_APinDescription[LED_BUILTIN].ulPort].OUTCLR.reg = (uint32_t)(1<<g_APinDescription[LED_BUILTIN].ulPin); // set pin mode to low transportDisable(); // Disable rfm69 __DSB(); if (debug) Serial.println("ZzZ (WFI)"); USBDevice.detach(); delay(5000); __WFI(); // Sleep delay(1000); PORT->Group[g_APinDescription[LED_BUILTIN].ulPort].OUTTGL.reg = (uint32_t)(1<<g_APinDescription[LED_BUILTIN].ulPin); // toggle output of built-in LED pin USBDevice.attach(); delay(10000); if (debug) Serial.println("Out of ZzZ (WFI)"); //transportReInitialise(); // Enable rfm69 delay(100); } void EIC_ISR(void) { //SLEEP_FLAG ^= true; // toggle SLEEP_FLAG by XORing it against true wakeupReason = "INTERRUPT"; } void sleepSetup() { SYSCTRL->XOSC32K.reg |= (SYSCTRL_XOSC32K_RUNSTDBY | SYSCTRL_XOSC32K_ONDEMAND); // set external 32k oscillator to run when idle or sleep mode is chosen REG_GCLK_CLKCTRL |= GCLK_CLKCTRL_ID(GCM_EIC) | // generic clock multiplexer id for the external interrupt controller GCLK_CLKCTRL_GEN_GCLK1 | // generic clock 1 which is xosc32k GCLK_CLKCTRL_CLKEN; // enable it while (GCLK->STATUS.bit.SYNCBUSY); // write protected, wait for sync EIC->WAKEUP.reg |= EIC_WAKEUP_WAKEUPEN4; // Set External Interrupt Controller to use channel 4 (pin 6) PM->SLEEP.reg |= PM_SLEEP_IDLE_CPU; // Enable Idle0 mode - sleep CPU clock only SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // Enable Standby or "deep sleep" mode if (debug) Serial.println("EO sleepsetup"); } -
Indeed you're right :) I have removed more and more coded to eliminate any causes and reduced it all to the bare minimum, nothing changed. Anyways, I added this to the above code:
#define CHILD_ID_MBXTRIP 52 MyMessage MbxTrip(CHILD_ID_MBXTRIP, V_TRIPPED); void presentation() { sendSketchInfo("Mbx", "2.0"); present(CHILD_ID_MBXTRIP, S_DOOR); }And here's the debug output:
11:54:19.036 -> 3084 TSM:FPAR:OK 11:54:19.036 -> 3084 TSM:ID 11:54:19.036 -> 3084 TSM:ID:OK 11:54:19.036 -> 3084 TSM:UPL 11:54:19.106 -> 3153 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1 11:54:19.748 -> 3399 TSF:MSG:READ,0-0-11,s=255,c=3,t=25,pt=1,l=1,sg=0:1 11:54:19.748 -> 3399 TSF:MSG:PONG RECV,HP=1 11:54:19.748 -> 3399 TSM:UPL:OK 11:54:19.748 -> 3399 TSM:READY:ID=11,PAR=0,DIS=1 11:54:19.748 -> 3475 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100 11:54:19.748 -> 3714 TSF:MSG:READ,0-0-11,s=255,c=3,t=15,pt=6,l=2,sg=0:0100 11:54:19.763 -> 3801 TSF:MSG:SEND,11-11-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.3.2 11:54:20.561 -> 4370 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0 11:54:22.599 -> 6437 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=11,pt=0,l=3,sg=0,ft=0,st=OK:Mbx 11:54:22.972 -> 7006 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:2.0 11:54:23.576 -> 7573 TSF:MSG:SEND,11-11-0-0,s=52,c=0,t=0,pt=0,l=0,sg=0,ft=0,st=OK: 11:54:23.576 -> 7574 MCO:REG:REQ 11:54:24.110 -> 8142 TSF:MSG:SEND,11-11-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2 11:54:24.538 -> 8383 TSF:MSG:READ,0-0-11,s=255,c=3,t=27,pt=1,l=1,sg=0:1 11:54:24.538 -> 8383 MCO:PIM:NODE REG=1 11:54:24.538 -> 8383 MCO:BGN:STP 11:54:24.538 -> EO sleepsetup 11:54:24.538 -> 8484 MCO:BGN:INIT OK,TSP=1 11:54:29.540 -> Going to sleep in 60 seconds... 11:55:29.782 -> REEDSWITCHPIN State: 6 11:55:29.782 -> 73484 TSF:TDI:TSL 11:55:29.782 -> ZzZ (WFI)Now, when I make D6 (REEDSWITCHPIN) go LOW by conneting to GND nothing happens (doesn't wake up). But removing all mysensors code makes it work
-
I may have solved/found a workaround for this, changing the interrupt to trigger on "LOW" instead of "FALLING" works for some reason :man-shrugging: