Add some rough power consumption values to pico_low_power (#3031)
* Add some rough power consumption values to pico_low_power
Also add RP2040 needing external clock for dormant to the note
Also fix incorrect invalid_params_if in low_power_go_dormant
* Unlock VREG before pstate change
Update power consumption values based off more measurements and this VREG change
* Add some values for lower power Pstates too
diff --git a/src/rp2_common/pico_low_power/include/pico/low_power.h b/src/rp2_common/pico_low_power/include/pico/low_power.h
index 115e156..3855a6b 100644
--- a/src/rp2_common/pico_low_power/include/pico/low_power.h
+++ b/src/rp2_common/pico_low_power/include/pico/low_power.h
@@ -24,7 +24,8 @@
* There are three modes of operation: sleep, dormant, and Pstate, with the lowest power consumption being Pstate.
*
* \if rp2040_specific
- * NOTE: On RP2040, there is no Pstate mode.
+ * NOTE: On RP2040, there is no Pstate mode, and going dormant using the AON timer requires an external clock
+ * source for the RTC (see \ref low_power_set_external_clock_source).
* \endif
*
* In sleep mode:
@@ -52,7 +53,20 @@
* - The Pstate APIs will overwrite the last 2 powman scratch registers - the other scratch registers are not modified,
* so can be used for other persistent data.
* \endif
+ *
+ * Some rough power consumption values when going to low power modes using timers, measured on Pico-series boards
+ * (powered either from VSYS at 5.2V, or from 3V3 at 3.3V, running low_power_test_simple):
*
+ * Mode | Pico (VSYS) | Pico 2 (VSYS) | Pico (3V3) | Pico 2 (3V3)
+ * ----------------------|----------------|-----------------|----------------|----------------
+ * Sleep | 7.3mA (37.9mW) | 5.9mA (30.7mW) | 8.7mA (28.5mW) | 6.9mA (22.7mW)
+ * Dormant | 0.76mA (4.0mW) | 3.3mA (17.0mW) | 0.75mA (2.5mW) | 3.7mA (12.0mW)
+ * Pstate (SRAM0 On) | N/A | 0.25mA (1.32mW) | N/A | 0.14mA (0.47mW)
+ * Pstate (XIP SRAM On) | N/A | 0.22mA (1.21mW) | N/A | 0.10mA (0.44mW)
+ * Pstate (All SRAM Off) | N/A | 0.18mA (1.10mW) | N/A | 0.08mA (0.40mW)
+ *
+ * NOTE: The RP2350 dormant values are higher than the RP2040 ones because RP2350 continues running clk_ref from the LPOSC to run the timer,
+ * whereas RP2040 requires an external clock input.
*/
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_PICO_LOW_POWER, Enable/disable assertions in the pico_low_power module, type=bool, default=0, group=pico_low_power
diff --git a/src/rp2_common/pico_low_power/low_power.c b/src/rp2_common/pico_low_power/low_power.c
index 80bf055..2559e56 100644
--- a/src/rp2_common/pico_low_power/low_power.c
+++ b/src/rp2_common/pico_low_power/low_power.c
@@ -122,6 +122,8 @@
powman_set_debug_power_request_ignored(true);
// Switch powman timer to lposc explicitly, which will also use the calibrated frequency
powman_timer_set_1khz_tick_source_lposc();
+ // Unlock VREG, so it can switch to low power mode
+ hw_set_bits(&powman_hw->vreg_ctrl, POWMAN_PASSWORD_BITS | POWMAN_VREG_CTRL_UNLOCK_BITS);
}
static void post_pstate_change(void) {
@@ -492,7 +494,7 @@
}
static void low_power_go_dormant(dormant_clock_source_t dormant_clock_source) {
- invalid_params_if(PICO_LOW_POWER,
+ valid_params_if(PICO_LOW_POWER,
dormant_clock_source == DORMANT_CLOCK_SOURCE_XOSC || dormant_clock_source == DORMANT_CLOCK_SOURCE_ROSC
#if !PICO_RP2040
|| dormant_clock_source == DORMANT_CLOCK_SOURCE_LPOSC