Snooze icon indicating copy to clipboard operation
Snooze copied to clipboard

startup_early_hook() taken by libSnooze

Open jhgorse opened this issue 4 years ago • 2 comments

Hello,

I need to use a watchdog timer (WDT) which requires defining startup_early_hook() code to initialize it correctly.

libSnooze uses the startup_early_hook() and provides no way to extend it (callback at the end) or provide a weak declaration so the user may override it with their definition (not sure if or how that works in C++).

I presume that the WDT is disabled for a reason in libSnoonze. Any hints as to why it was disabled would be cool. And how I might get by with enabling WDT, but I won't stretch my luck.

Cheers, Joe

jhgorse avatar Jan 21 '21 17:01 jhgorse

Thanks for the issue I'll see what I can do when I start looking at Snooze again in the not to distant future.

The startup_early_hook() is used for a sleep modes that wakes with a reset, but I'll look into a way to give the user access to it also.

duff2013 avatar Jan 23 '21 19:01 duff2013

I had the same issue on a Teensy 3.6, ended up changing this line: https://github.com/duff2013/Snooze/blob/4ae33c6ec8284c7b3f27d867a1357d32c063bec9/src/hal/TEENSY_36/hal.c#L842 to:

__attibute__((weak)) void startup_early_hook( void ) { 

then overwriting that in my main.ino file to setup my watchdog time using

// Setup watchdog timer
#ifdef __cplusplus
  extern "C" {
    // Overwrites startup_early_hook() in Snooze/src/hal/TEENSY_36/hal.c
    void startup_early_hook() {
      // clock source 0 LPO 1khz, 15 s timeout
      WDOG_TOVALL = 15000; // Sets the time-out value. This is the value that the watchdog timer compare itself to in ms.
      WDOG_TOVALH = 0;
      WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE); // Enable WDG
      WDOG_PRESC = 0; // Prescaler
    }
  }
#endif

Heres a minimum working example on a Teensy 3.6 of sleep with watchdog timer.

/*
 * Turns on and off the built-in LED whenever the watchdog timer resets.
 * Watchdog is triggered if the watchdog timer hasn't been reset in less than 15 seconds.
 * Normal operation keeps the watchdog timer reset ~10 seconds.
 */

#define LOW_POWER

#ifdef LOW_POWER
  #include <Snooze.h>
  SnoozeUSBSerial usb;
  SnoozeAlarm alarm;
  SnoozeBlock sleepConfig(usb, alarm);
#endif // LOW_POWER

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  #ifdef LOW_POWER
    alarm.setRtcTimer(0, 0, 10); // Set alarm to wake up
  #endif // LOW_POWER

  watchDogReset();
}

// Setup watchdog timer
#ifdef __cplusplus
  extern "C" {
    // Overwrites startup_early_hook() in Snooze/src/hal/TEENSY_36/hal.c
    void startup_early_hook() {
      // clock source 0 LPO 1khz, 15 s timeout
      WDOG_TOVALL = 15000; // Sets the time-out value. This is the value that the watchdog timer compare itself to in ms.
      WDOG_TOVALH = 0;
      WDOG_STCTRLH = (WDOG_STCTRLH_ALLOWUPDATE); // Enable WDG
      WDOG_PRESC = 0; // Prescaler
    }
  }
#endif

void watchDogReset() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  noInterrupts();
  WDOG_REFRESH = 0xA602;
  WDOG_REFRESH = 0xB480;
  interrupts();
}

void loop() {

  #ifdef LOW_POWER
    Snooze.sleep(sleepConfig); // Go to sleep
  #endif // LOW_POWER
  
  watchDogReset();
}

Not sure if I have disrupted the functionality of other aspects of the Snooze library by making this change.

HarveyBates avatar May 02 '22 04:05 HarveyBates