-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
nrf/modules/machine: Implement deepsleep() #13367
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
base: master
Are you sure you want to change the base?
Conversation
Code size report:
|
OK, apparently this doesn’t work on the nRF9160. Will investigate. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #13367 +/- ##
==========================================
- Coverage 98.39% 98.39% -0.01%
==========================================
Files 161 161
Lines 21200 21078 -122
==========================================
- Hits 20860 20739 -121
+ Misses 340 339 -1 ☔ View full report in Codecov by Sentry. |
92e55d1
to
e002e18
Compare
Builds on all boards now. No idea if it works on the nRF9160, as I don’t have one to test, but apart from the different register its System OFF mode looks similar. |
When implementing lightsleep/deepsleep for the SAMD port, I went for taking all pins as wake-up source which had IRQ enabled. That avoids another Pin argument. Besides that, an additional argument may better be called |
Rebased on master to deal with the STATIC removal, no other changes required. |
Thanks for the contribution. Is it possible to split up the second commit into two commits:
The first part there can be merged easily. The change to |
Replace the previous dummy implementation of machine.deepsleep() with one that invokes the nRF's deep sleep state "System OFF". The argument is ignored, nRF microcontrollers are incapable of waking on a timer as all clocks are off in the deep sleep state. There is no way yet to wake from deep sleep except using the reset pin, a way to configure GPIO pins as wake sources is to be added in a subsequent commit. machine.reset_cause() returns the newly added DEEPSLEEP_RESET, like on other ports – the previous mapping to PWRON_RESET seemed wrong. Signed-off-by: Christian Walther <cwalther@gmx.ch>
Pins are configured as wake sources for deep sleep using an additional port-specific argument "sense" to the machine.Pin constructor. Signed-off-by: Christian Walther <cwalther@gmx.ch>
Splitting seems like a good way forward, done. Not thoroughly tested yet, will do that in a few days. I agree that how to configure pins for waking needs more thought and discussion. |
Can the deepsleep commit be merged? |
So, I've been looking at putting my NRF52840 Xiao board into deep sleep. @cwalther's implementation does indeed put the nrf52 to sleep, but it still consumes a lot of current. After looking for a reason on Arduino forums, I found that the Xiao board has a qspi flash memory chip on it, and it needs to be put to sleep. Arduino people have had success using Adafruit SPIflash library that sends command 0xB9 to the qspi chip, then de-initing the qspi interface. In Nordic's documentation, they also show a way to do it with the registers. I don't know if many nrf boards use qspi flash memory, but I feel like for the deepsleep() function to be consistant with other ports, the qspi should be put to sleep also. I'd propose a change myself, but I'm not well versed in C, and I haven't been able to put the flash chip to sleep only using micropython. I wonder if something in the drivers keeps it from entering sleep mode, since it would prevent micropython from working properly. |
Good point. There does seem to be precedent for board-specific deep-sleep handling dealing with SPI flash in some STM32 boards using the MICROPY_BOARD_ENTER_STANDBY macro. So I agree that this could be added here too. However, I would consider that an additional change that can go in a separate pull request (based on this one), and I currently have no plans to work on this in the near future. |
Replace the previous dummy implementation of
machine.deepsleep()
with one that invokes the nRF's deep sleep state System OFF. The argument is ignored, nRF microcontrollers are incapable of waking on a timer as all clocks are off in the deep sleep state.Pins are configured as wake sources using an additional argument
sense
to themachine.Pin
constructor. This choice is up for debate, it seemed appropriate because it internally is a matter of GPIO configuration. I also considered using the unusedwake
argument toPin.irq()
, but rejected that because the configuration has nothing to do with IRQs. Another possibility would be a special function in thenrf
module, akin toesp32.wake_on_ext0()
.machine.reset_cause()
returns the newly addedDEEPSLEEP_RESET
, like on other ports – the previous mapping toPWRON_RESET
seemed wrong.I am unsure where to document this, as there is no port-specific documentation for the nrf port. Should I add a Quick reference for the nRF51/52 section just for this?
Tested on nRF52832 (DS-D6) and nRF52840 (ItsyBitsy).