Skip to content

powman_configure_wakeup_state() always fails on Pico 2W with SDK 2.2.0 #2823

@flaviorenga

Description

@flaviorenga

powman_configure_wakeup_state() always fails on Pico 2W with SDK 2.2.0

Environment

  • Board: Raspberry Pi Pico 2W (RP2350)
  • SDK Version: 2.2.0
  • Build System: CMake 3.13+
  • Toolchain: ARM GCC 14_2_Rel1
  • Platform: PICO_BOARD=pico2_w

Problem Description

I'm trying to use the POWMAN API to put the RP2350 into a low-power dormant state, but powman_configure_wakeup_state() always returns false (failure) for every possible power state combination.

Current Consumption

  • Active (with CYW43 WiFi on): ~60mA ✅ (expected)
  • Active (with CYW43 WiFi off): ~30mA ✅ (GPIO23 control works)
  • Attempting dormant: Fails immediately, never enters low-power mode ❌

Goal

Achieve <2mA consumption in dormant mode by:

  1. Disabling CYW43 WiFi chip (GPIO23 = LOW)
  2. Entering POWMAN low-power state
  3. Waking up via GPIO interrupt

What I've Tried

Test 1: Basic Configuration (SWCORE + SRAM0)

gpio_put(23, 0);  // Disable CYW43
powman_set_debug_power_request_ignored(true);

powman_power_state sleep_state = 0;
sleep_state = powman_power_state_with_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SWITCHED_CORE);
sleep_state = powman_power_state_with_domain_on(sleep_state, POWMAN_POWER_DOMAIN_SRAM_BANK0);

powman_power_state wakeup_state = sleep_state;  // Same state

bool result = powman_configure_wakeup_state(sleep_state, wakeup_state);
// result is FALSE ❌

Result: powman_configure_wakeup_state() returns false

Test 2: Tried ALL Possible Power State Combinations

I systematically tested every possible combination of power domains:

Configuration Binary Hex Result
SWCORE only 1000 0x08 ❌ FAILED
SWCORE + SRAM0 1010 0x0a ❌ FAILED
SWCORE + SRAM1 1001 0x09 ❌ FAILED
SWCORE + SRAM0 + SRAM1 1011 0x0b ❌ FAILED
SWCORE + XIP 1100 0x0c ❌ FAILED
SWCORE + XIP + SRAM0 1110 0x0e ❌ FAILED
ALL domains 1111 0x0f ❌ FAILED

Every single combination fails!

Test 3: Verified POWMAN Register State

printf("CURRENT_PWRUP_REQ:  0x%08lx\n", powman_hw->current_pwrup_req);
printf("LAST_SWCORE_PWRUP:  0x%08lx\n", powman_hw->last_swcore_pwrup);
printf("DBG_PWRCFG:         0x%08lx\n", powman_hw->dbg_pwrcfg);
printf("SEQ_CFG:            0x%08lx\n", powman_hw->seq_cfg);

Output:

CURRENT_PWRUP_REQ:  0x00000000
LAST_SWCORE_PWRUP:  0x00000001
DBG_PWRCFG:         0x00000001
BOOTDIS:            0x00000000
DBGCONFIG:          0x00000000
SEQ_CFG:            0x001011f0

No pending power requests blocking the configuration.

Test 4: Tried with POWMAN BOOT Registers

Attempted to use BOOT registers for resume-in-place (as per mamba2410's example):

powman_hw->boot[0] = (uint32_t)wakeup_vector;
uint32_t sp;
__asm volatile ("mov %0, sp" : "=r" (sp));
powman_hw->boot[1] = sp;

bool result = powman_configure_wakeup_state(sleep_state, wakeup_state);
// Still returns FALSE ❌

Result: Still fails

Test 5: Verified CYW43 Control Works

GPIO23 successfully controls the CYW43 WiFi module:

  • gpio_put(23, 1) → consumption rises from 30mA to 60mA ✅
  • gpio_put(23, 0) → consumption drops from 60mA to 30mA ✅

So hardware control is working correctly.

Code Example (Minimal Reproduction)

#include "pico/stdlib.h"
#include "hardware/powman.h"

int main() {
    // Disable CYW43
    gpio_init(23);
    gpio_set_dir(23, GPIO_OUT);
    gpio_put(23, 0);
    sleep_ms(100);
    
    powman_set_debug_power_request_ignored(true);
    
    powman_power_state state = 0;
    state = powman_power_state_with_domain_on(state, POWMAN_POWER_DOMAIN_SWITCHED_CORE);
    state = powman_power_state_with_domain_on(state, POWMAN_POWER_DOMAIN_SRAM_BANK0);
    
    bool ok = powman_configure_wakeup_state(state, state);
    
    if (!ok) {
        // This ALWAYS executes - function always fails!
        while(1) {
            gpio_put(LED_PIN, 1);
            sleep_ms(100);
            gpio_put(LED_PIN, 0);
            sleep_ms(100);
        }
    }
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico2_w CACHE STRING "Board type")
include(pico_sdk_import.cmake)
project(test C CXX ASM)
pico_sdk_init()

add_executable(test test.c)
target_link_libraries(test pico_stdlib hardware_powman hardware_clocks)
pico_add_extra_outputs(test)

Questions

  1. Is powman_configure_wakeup_state() expected to work on Pico 2W?

    • Does the CYW43 WiFi chip impose additional constraints?
    • Are there undocumented requirements for the Pico 2W variant?
  2. Why does every power state combination fail?

    • The function rejects even the simplest configurations
    • No combination of domains is accepted
  3. Should I use the legacy xosc_dormant() method instead?

    • Is POWMAN on RP2350 stable/production-ready?
    • Are there known issues with Pico 2W specifically?
  4. Are there working examples for Pico 2W + POWMAN?

    • I've tested peterharperuk's powman examples but they target Pico 2 (non-W)
    • Can someone confirm POWMAN works on Pico 2W hardware?

Related Issues/Discussions

Expected Behavior

powman_configure_wakeup_state() should:

  1. Return true for at least one valid power state configuration
  2. Allow the system to enter dormant mode consuming <2mA
  3. Wake up via GPIO interrupt

Actual Behavior

powman_configure_wakeup_state() always returns false for every configuration tested, making it impossible to use POWMAN on Pico 2W.


Any help or guidance would be greatly appreciated! 🙏

Is this a known limitation? Is there a workaround? Should I stick with the legacy RP2040-style dormant methods for now?

Thank you in advance for any assistance.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions