Power.Sleep Problems

I’ve been having problems getting Power.Sleep() to wake up reliably on button-press which seem to be connected to use of the USB, however while trying to isolate by starting out with the basic example in the docs I came across this beauty.
This code fragment is inside a loop, with the boolean WantSleep set from an interrupt triggered by the Down button. When set it does a Sleep/Hibernate for 5 seconds. The rest of the loop just flashes a LED so I can see if it is working without the debugger connected.

            if(WantSleep)
            {
                DateTime wTime = DateTime.Now.AddSeconds(5);
                WantSleep = false;
                Debug.WriteLine("Now: " + DateTime.Now + " Rtc: " + rtc.Now + " SleepUntil: " + wTime);
                Power.Sleep(wTime);
                Debug.WriteLine("AwakeAt: " + DateTime.Now + " Rtc: " + rtc.Now);
            }

And the output is:

Down Button!
Now: 01/25/2023 13:02:49 Rtc: 01/25/2023 13:02:49 SleepUntil: 01/25/2023 13:02:54
AwakeAt: 01/25/2023 13:02:49 Rtc: 01/25/2023 13:02:55
Down Button!
Now: 01/25/2023 13:03:26 Rtc: 01/25/2023 13:03:32 SleepUntil: 01/25/2023 13:03:31
AwakeAt: 01/25/2023 13:03:26 Rtc: 01/25/2023 13:03:32
Down Button!
Now: 01/25/2023 13:03:27 Rtc: 01/25/2023 13:03:32 SleepUntil: 01/25/2023 13:03:32
AwakeAt: 01/25/2023 13:03:27 Rtc: 01/25/2023 13:03:33
Down Button!
Now: 01/25/2023 13:04:24 Rtc: 01/25/2023 13:04:30 SleepUntil: 01/25/2023 13:04:29
AwakeAt: 01/25/2023 13:04:24 Rtc: 01/25/2023 13:04:30
Down Button!
Now: 01/25/2023 13:04:24 Rtc: 01/25/2023 13:04:30 SleepUntil: 01/25/2023 13:04:29

and then it never wakes up.
You can see DateTime.Now drifting back from Rtc.Now at each call until the wakeup time is in the past.

So it appears that:

  1. The system time (DateTime.Now) isn’t updated while suspended.
  2. The Wake time is based on the Rtc time
  3. If the Wake time is in the past, it will never wake up

I would suggest that:

  1. You are generally better off having a Wake after a given period, rather than at a specific time. If not the default, this should be an option.
  2. If you are going to Wake at a specific time then the clock used should be the same one as is used for the timing. (So perhaps change the example to use Rtc.Now ?)
  3. If the user asks to wake up in the past, better to wake immediately than never!
  4. When coming out of Sleep the system time should be updated to the Rtc time (optionally?), or at least this should be noted in the documentation with the example wrapper code.

When I first started testing with the Power.Sleep() example code I was getting exceptions with no clear reason, which I eventually worked out were because the Rtc wasn’t set. Perhaps this could be documented, or better still done away with - not all applications require an Rtc, so perhaps if Rtc isn’t valid on a call to Power.Sleep() it could be automatically set to a default value?