-
Notifications
You must be signed in to change notification settings - Fork 4
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
I think there is a need to turn off systick interrupts during sleep #3
Comments
Chris - Thank you for taking the time to diagnose/document/fix this issue. It's been a while since I've looked at this code so I may need you to guide me through this a little. So that we are both on the same page, I assume this is the errata you are referring to? I agree, this could certainly be a problem. So far, I understand disabling/re-enabling the systick interrupt in your code. I'm not clear on why you added this. This leaves powering down the flash. Potential Lockup on Standby Wakeup with Arm Core PRIMASK=1 I believe we are okay here because we only exit sleep through an interrupt and so PRIMASK must be 0 unless we are catching an NMI. So, I guess to be safe we would need to keep the flash from sleeping. I would like to make some measurements before making this the default configuration. I was quite pleased with achieving 6 uA of sleep current and if keeping the flash ouf of sleep is going to make a significant difference maybe make an NMI sleep function and a non-NMI function. Let me know your thoughts on this and thanks again. |
thank you for the reply.
You are right, the data sheet indicates that the DEEPSLEEP should supersede the idle code. On the flash memory, I will make some tests to see if there is any problem keeping it off. I'm not using NMI (at least explicitly). I think the reason it (and the idle) crept into my mods is that I'd looked at another low power library that used them. I'll make some tests (it may take a while).
Chris H
…________________________________
From: ee-quipment.com ***@***.***>
Sent: Monday, January 24, 2022 3:02:51 PM
To: ee-quipment/ZeroPowerManager
Cc: Hayward, Chris; Author
Subject: Re: [ee-quipment/ZeroPowerManager] I think there is a need to turn off systick interrupts during sleep (Issue #3)
[EXTERNAL SENDER]
I found that without the mod for SysTick, the system from time to time will hang (perhaps one time out of a thousand) at least for the code I was running. There is an errata in the ATSAMD21 datasheet that confirms that systick interrupts needs to be disabled during sleep.
void zpmSleep(void) { NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val; //cth - make sure FLASH does not pwoer all the way down in sleep SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; //cth to fix hangs SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; PM->SLEEP.reg = 2; //idle mode __DSB(); __WFI(); SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; //restore }
Chris -
Thank you for taking the time to diagnose/document/fix this issue. It's been a while since I've looked at this code so I may need you to guide me through this a little.
So that we are both on the same page, I assume this is the errata you are referring to?
1.5.7 Potential Lockup on Standby Entry
When the Systick interrupt is enabled, a device lockup can occur when the Systick interrupt coincides with the
standby entry.
Workaround
Disable the Systick interrupt before entering standby and re-enable it after wake up.
I agree, this could certainly be a problem.
So far, I understand disabling/re-enabling the systick interrupt in your code.
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; //cth to fix hangs
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; //restore
I'm not clear on why you added this.
PM->SLEEP.reg = 2; //idle mode
My understanding is that setting SLEEPDEEP supercedes this. I experimented with the idle modes back when I wrote this and found they don't really make much of a difference in power consumption.
This leaves powering down the flash.
NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val; //cth - make sure FLASH does not pwoer all the way down in sleep
Is this because of errata 1.5.8 ?
Potential Lockup on Standby Wakeup with Arm Core PRIMASK=1
Upon wake up from standby with Arm Core register PRIMASK = 1, the first instruction fetched by the CPU in
Flash memory will be the first instruction following the WFI. This instruction may be returned corrupted and lead to
unpredictable behavior.
If PRIMASK = 0, the first instruction fetched by the CPU will be the first instruction of the interrupt handler. This one
will be correctly returned to the CPU.
I believe we are okay here because we only exit sleep through an interrupt and so PRIMASK must be 0 unless we are catching an NMI. So, I guess to be safe we would need to keep the flash from sleeping. I would like to make some measurements before making this the default configuration. I was quite pleased with achieving 6 uA of sleep current and if keeping the flash ouf of sleep is going to make a significant difference maybe make an NMI sleep function and a non-NMI function.
Let me know your thoughts on this and thanks again.
—
Reply to this email directly, view it on GitHub<#3 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AQKEQKG2VQIEOTOW5DAUPZLUXW47XANCNFSM5MQ7EZKQ>.
Triage notifications on the go with GitHub Mobile for iOS<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675> or Android<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
I found that without the mod for SysTick, the system from time to time will hang (perhaps one time out of a thousand) at least for the code I was running. There is an errata in the ATSAMD21 datasheet that confirms that systick interrupts needs to be disabled during sleep.
void zpmSleep(void) {
NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val; //cth - make sure FLASH does not pwoer all the way down in sleep
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; //cth to fix hangs
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
PM->SLEEP.reg = 2; //idle mode
__DSB();
__WFI();
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; //restore
}
The text was updated successfully, but these errors were encountered: