Skip to content
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

Disable SAMD21 SysTick interrupt during sleep and correct SAMD20/21 defines #24

Merged
merged 2 commits into from May 18, 2022
Merged

Conversation

ghost
Copy link

@ghost ghost commented Jun 18, 2020

This pull request addresses two separate issues.

The first is in response to the issue: "strange reset on Feather M0 after random minutes", raised here: #9.

Disabling the systick timer interrupt during sleep has previously been discussed on the Microchip/Atmel community forum: https://community.atmel.com/comment/2625116#comment-2625116.

In summary, due to a hardware bug on the SAMD21, the SysTick interrupts become active before the flash has powered up from sleep, causing a hard fault after a random time. To prevent this the SysTick interrupts are disabled before entering sleep mode and enabled oncemore after the processor has woken up:

SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;  // Disable SysTick interrupts
__DSB();   // Data sync to ensure outgoing memory accesses complete
__WFI();   // Wait for interrupt (places device in sleep mode)
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;   // Enable SysTick interrupts

The second issue, is that to the best of my knowledge the SAMD20 and SAMD21 definitions do not exist, either in the included "sam.h" file or anywhere else. I've tested the definitions with a small sketch and SAMD21 remains undefined. This means that the line that prevents the RAM from powering down during sleep never gets called:

#if (SAMD20 || SAMD21)
  // Don't fully power down flash when in sleep
  NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val;
#endif

The "sam.h" file does however provide a SAMD21_SERIES define and earlier versions also include SAMD20_SERIES, these encompass all the SAMD20/SAMD21 variants:

#if (SAMD20_SERIES || SAMD21_SERIES)

I've tested the code on a SAMD21, however I'm unable to test on a SAMD20. I've assumed that the SAMD20 also being an ARM Cortex M0+ exhibits the same behaviour as the SAMD21. The SAMD51 code remains unaffected by these changes.

@ghost
Copy link
Author

ghost commented Jun 18, 2020

Oops, looks like I've done somthing wrong. I'll start again.

@ghost ghost closed this Jun 18, 2020
@ghost
Copy link
Author

ghost commented Jun 18, 2020

I decided to repen the pull request, not sure why the Arduino Library CI is failing?

@ghost ghost reopened this Jun 18, 2020
@PaintYourDragon PaintYourDragon merged commit b95520f into adafruit:master May 18, 2022
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.

1 participant