Skip to content

Fix SysTick timer lockup when waking from sleep #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

sslupsky
Copy link
Contributor

@sslupsky sslupsky commented May 8, 2019

While researching some low power issues I came across a discussion regarding a situation that can lead to a lockup and hard fault when waking from sleep. The issue is discussed on this AVRFreaks thread:

https://www.avrfreaks.net/forum/samd21-samd21e16b-sporadically-locks-and-does-not-wake-standby-sleep-mode

Microchip has acknowledged to problem:

We have identified the issue with WDT reset. It happens due to SysTick timer.

Issue is that WDT initiates the wake up, but then SysTick interrupt starts to get handled first before system is actually ready. Basically, what happens is that SysTick interrupt does not wait for the RAM to properly wake up from sleep.

So if you wake up from WDT, the system will wait for the RAM, but the core clock will actually be running, so SysTick interrupt may happen too. SysTick interrupt does not wait on the RAM, so the core attempts to run the SysTick handler and fails, since RAM is not ready. This causes a Hard Fault (in our testing SRAM is so slow to wake up even Hard Fault handler).

This mean that device wakes up, getting into the Hard Fault, stay there until WDT fully expires.

You can reproduce the issue quicker by running SysTick timer faster, and WDT wake ups also quicker.

The solution for the customer is to disable SysTick interrupt before going to sleep and enable it back after the sleep.

// Disable systick interrupt
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
// Deep sleep
sleepmgr_sleep(SLEEPMGR_STANDBY);
// Enable systick interrupt
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;

The attached PR includes these changes to the sleep() method.

@facchinm
Copy link
Contributor

LGTM! Merging, thanks for the contribution!

@facchinm facchinm merged commit 892594a into arduino-libraries:master May 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants