-
Notifications
You must be signed in to change notification settings - Fork 431
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
Feature Request: support deep sleep for the RP2350 #2528
Comments
I'm pretty sure the code sample you got isn't close to correct, but there are good examples from the RPI folks directly in the I still haven't found out where my USB power monitor migrated to so don't really have the equipment to do this myself. If someone wants to give ti a go, I'd be happy to get it in here. The interesting bit will be getting the system and core back into a consistent state after restart. Things like which clocks are on, what the USB state is, which blocks are enabled (ADC, PWM, timer, etc.). Requiring the user to assume the board is equivalent to power on (but with valid RAM) might be fine, but the core internal state will need to be updated to reflect whatever is chosen... |
For the RP2350 there is at least the powman (power manager) API that can switch off certain things. And the CMSIS headers for the ARM Cortex-M33 and the RISC-V Hazard3 probably also have functions to go into a sleep state (wait for interrupt, etc.). Also related to adafruit/circuitpython#9491 and raspberrypi/pico-playground#48 |
I need x-low power consumption from a uC for an off-grid project I've undertaken. I'd like to use the Pico for this as I've done another project (controlling an INA260) using a Pico 1. However: I have tried the I'm posting to ask about the status of "deep sleep" here: does it appear feasible/do-able, any thoughts on the timeline?? My alternative for the Pico is a TI MSP430 - they have sleep examples that actually work :) |
I just tested some code found in the RP2040 datasheet and ran it on my Pico (1). The DORMANT sleep with GPIO wakeup worked just fine. Here's the sketch: #include <Arduino.h>
#include <hardware/xosc.h>
#define GPIO_EXIT_DORMANT_MODE 3 /* connect GP3 to GND once in DORMANT mode */
void setup() {
Serial1.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
pinMode(GPIO_EXIT_DORMANT_MODE, INPUT_PULLUP); // pull pin that will get us out of sleep mode
}
void loop() {
if (Serial1.available() > 0) {
(void) Serial1.read();
digitalWrite(LED_BUILTIN, LOW);
// this interrupt source will get us out of the DORMANT mode agin
gpio_set_dormant_irq_enabled(GPIO_EXIT_DORMANT_MODE, IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_EDGE_LOW_BITS, true);
// disable systick now so that no milisecond interrupts will occur
systick_hw->csr &= ~1;
// we will get out of sleep when an interrupt occurs.
// this will shutdown the crystal oscillator until an interrupt occurs.
xosc_dormant();
// this will only be reached after wakeup.
gpio_acknowledge_irq(GPIO_EXIT_DORMANT_MODE, IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_EDGE_LOW_BITS); // acknowledge GPIO IRQ
systick_hw->csr |= 1; // enable systick again, hope we survived this
// we don't actually know the time duration during which we were dormant.
// so, the absolute value ofmillis() will be messed up.
digitalWrite(LED_BUILTIN, HIGH);
}
Serial1.println("hello, world");
delay(500);
} note that this was compiled with the USB stack off, so The sketch waits on a character to be received via UART, then it will set the crystal oscillator into dormant mode. Before that, GP3 is registered as a wakeup source, expecting a falling edge. With a Nordic PPK2, I was able to measure the current going into the 5V "VBUS" line. So, this measures the entire current draw of the Pico board at 5V, and not just that of the RP2040 processor. I can clearly see that, once I send the UART character, the current draw drops dramatically, from an average of 23.54mA to 2.10mA (at 5V). |
The |
Mhm, the Pico datasheet claims 0.8mA @ 5V in DORMANT mode (source).. If I manually copy in the pico_sleep and hardware_rosc component from above (with a few mods to get rid of stdio reinit and enable a GPIO pullup) and do a sleep_run_from_dormant_source(DORMANT_SOURCE_XOSC);
sleep_goto_dormant_until_pin(GPIO_EXIT_DORMANT_MODE, true, false); I do get down to 1.88mA. Something is still missing here.. maybe a perpiheral is on, or some other component on the board is drawing power. In any case, enough experiments for today. |
Off the cuff, maybe try setting all GPIOs to Also probably want to |
That's a big help - thank you! Uh... where is the "RP2040 datasheet" where you found this?
I think that is for the Pico 2350 instead of the 2040. It appears they have deleted the code they had posted for the RP2040. ?? At least, I can't find it. |
The pico_sleep component works on both RP2040 and RP2350 chips, it differentiates between them using |
Excuse me please, but I still don't understand what you mean by "code found in the RP2040 datasheet". Can you provide some clarification - or a link to that code? I have looked in the Raspberry Pi Pico Datasheet, but I find no code in there. I'm also confused by the source of the code you posted in your earlier comment... It's not the same as this 'hello_dormant' example in the Pico Playground repo. Where do I find this code? My apologies for acting as a nincompoop, but I'm not really familiar at all with this |
I wouldn't know where to start so I asked the One Who Is Wrong With Confidence (ChatGPT) for an example and got some sample code which probably was not worth sharing (so I've deleted the noise I originally posted).
However, I figure we need an open ticket for this feature since this is one of the improvements of the RP2350 over the RP2040.
Would we want to add some RISC-V specific functionality to the RP2040 class for this?
The two typical use cases for deep sleep are:
The text was updated successfully, but these errors were encountered: