arduino-libraries / RTCZero

RTC Library for SAMD21 based boards
http://arduino.cc/en/Reference/RTC
GNU Lesser General Public License v2.1
76 stars 79 forks source link

Suggestion: standbyMode() should adopt the sleep() code in the ArduinoLowPower library #68

Open sergerold opened 3 years ago

sergerold commented 3 years ago

Hi

These functions are designed to do the same thing but the sleep() function has a number of advantages (e.g. disabling systick) which can cause issues

// RTCZero.cpp
void RTCZero::standbyMode()
{
  // Entering standby mode when connected
  // via the native USB port causes issues.
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  __DSB();
  __WFI();
}
// ArduinoLowPower.cpp
void ArduinoLowPowerClass::sleep() {
    bool restoreUSBDevice = false;
    if (SERIAL_PORT_USBVIRTUAL) {
        USBDevice.standby();
    } else {
        USBDevice.detach();
        restoreUSBDevice = true;
    }
    // Disable systick interrupt:  See https://www.avrfreaks.net/forum/samd21-samd21e16b-sporadically-locks-and-does-not-wake-standby-sleep-mode
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; 
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __DSB();
    __WFI();
    // Enable systick interrupt
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;  
    if (restoreUSBDevice) {
        USBDevice.attach();
    }
}

Thanks

adamgarbo commented 3 years ago

I agree that the systick interrupt change should be added, but would note that code in the ArduinoLowPower library prevents the serial port from being reestablished after deep sleep. Currently, this does not occur when manually calling USBDevice.detach() and USBDevice.attach() and using the RTCZero standbyMode() functionality.

I also wonder if the ArduinoLowPower library is attaching and detaching the USBDevice even when no USB connection is present. If so, it could be a good idea to have an auto-detect, or a user-configurable option to not have this action taken.