I have a question that I cannot seem to find the answer to in the Microchip datasheet for the SAMD21. How long does it take for the SAMD21 to wake from deep sleep? The corollary to this question, how long does it take for the SAMD21 to go to sleep is another question I have.
Let me explain some observations. I have a sketch that uses the RTCZero and Arduino Low Power libraries. My main loop wakes, resets a watch dog, checks a couple variables and then goes to sleep. Once every 60 seconds it blinks an LED. The wake-sleep RTC cycle is 10 seconds. That is, every 10 sections the RTC wakes the processor from sleep. When I wake, I toggle an I/O high immediately when I wake and toggle the same I/O low immediately before I go back to sleep.
The "wake" time according to the scope trace is about 6ms. This is the time the I/O pin is in its high state, meaning the time it goes high immadiately after waking and going low immediately before sleeping again. This amount of time seems extraordinarily high to me. Here is the loop:
void loop() {
Watchdog.reset();
// blink(1, BLINK_DURATION_SHORT, BLINK_LEVEL_VERBOSE, CRGB::Green);
uint32_t t;
t = rtc.getEpoch();
if ( t >= temperatureSampleTick ) {
// int i = NVConfig.temperatureSamplePeriod;
temperatureSampleTick += TEMPERATURE_PERIOD;
// readSensors();
// blink(1, BLINK_DURATION_SHORT, BLINK_LEVEL_VERBOSE, CRGB::Green);
// Log.verbose(F("[%l] level=verbose Temperature Tick" CR), millis());
}
if ( t >= heartBeatTick ) {
blink(1, BLINK_DURATION_SHORT, BLINK_LEVEL_VERBOSE, CRGB::Green);
heartBeatTick += HEARTBEAT_PERIOD;
// Log.verbose(F("[%l] level=verbose Heartbeat Tick" CR), millis());
}
if ( hostDataAvailable > 0 ) {
int i;
// Log.verbose(F("[%l] level=verbose Received %d bytes from MKRDOCK: "), millis(), hostDataAvailable);
for ( i = 0; i < hostDataAvailable; i++ ) {
if ( i < (hostDataAvailable - 1) ) {
// Log.verbose(F("%X, "), hostCommandBuf[i]);
} else {
// Log.verbose(F("%X" CR), hostCommandBuf[i]);
}
}
blink(1, BLINK_DURATION_SHORT, BLINK_LEVEL_VERBOSE, CRGB::Magenta);
hostDataAvailable = 0;
}
if ( hostDataRequest ) {
// blink(1, BLINK_DURATION_SHORT, BLINK_LEVEL_VERBOSE, CRGB::Blue);
// Log.verbose(F("[%l] level=verbose Host Requested Data" CR), millis());
hostDataRequest = false;
}
// blink(1, BLINK_DURATION_SHORT, BLINK_LEVEL_VERBOSE, CRGB::Green);
// Serial.flush();
// Detach and reattach USB device before and after sleep.
// See https://github.com/arduino-libraries/ArduinoLowPower/pull/8
USBDevice.detach();
digitalWrite(HOST_INT1, LOW);
LowPower.deepSleep();
digitalWrite(HOST_INT1, HIGH);
USBDevice.attach();
}
What is even stranger is looking at the current consumption. The current increases as if coming out of sleep about 35 ms before I see the I/O pin toggle high. Moreover, the current consumption remains high after the I/O pin toggle for an additional 10ms. Total width of the "current spike" when the device comes out of sleep is about 55ms. This is about 10x more than the time observed looking at the I/O pin.
This seems to suggest that the device is in some "waking" state before resuming execution and a "going to sleep state" before the power is shut down.
I am trying to understand better how the SAMD21 wakes and goes to sleep. The only information I can find in the datasheet that might begin to explain what is going on is related to the "lock time" for the DFLL48M oscillator. This can be up to 500us according to the datasheet (Table 37-52). Does resumption of the execution get delayed by the lock time of the DFLL? The lock time is about 100x less than the delay I am seeing though so I do not think this is the culprit.
Has anyone else make any observations on the current versus apparent wake time of the SAMD21? Does anyone have any ideas that could be causing this?