Skip to content

GPIO driver support for RW61x PM3 #89355

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

Closed
wants to merge 4 commits into from

Conversation

davidmissael
Copy link
Contributor

THIS IS A PRELIMINARY SOLUTION TO HELP CONTINUE THE DRIVER'S SUPPORT FOR POWER MANAGEMENT ON RW61x DEVICES
On RW61x devices, when entering in PM3, all peripheral lose their state/context. After exiting from this power mode, that context needs to be restored. This PR saves the GPIOs registers before entering to PM3 and restores the registers after exiting PM3, this helps the application recover all GPIOs configurations when returning from this power mode.

DerekSnell and others added 2 commits April 28, 2025 08:33
…x devices.

RW61x devices loses peripheral context when entering into PowerMode 3, so when
exiting form this power mode, it is necesary to restore all context. This is a
preliminary solution until who is responsible to restore this context and to
know the zephyr's contract for Power Management.

Signed-off-by: Missael Maciel <[email protected]>
…x devices

RW61x devices loses peripheral context when entering into PowerMode 3, so when
exiting from this power mode, it is necesary to restore all context.
This is a preliminary solution until definition on the responsible to
save the context for the GPIO peripheral.

Signed-off-by: Missael Maciel <[email protected]>
… devices

RW61x devices loses peripheral context when entering into PowerMode3, so when
exiting from this power mode, it is necessary to restore all context.
This is a preliminary solution until zephyr contract defines whis is responsible
to save and restore context for GPIO peripheral.

Signed-off-by: Missael Maciel <[email protected]>
@DerekSnell DerekSnell marked this pull request as draft May 1, 2025 16:06
@davidmissael
Copy link
Contributor Author

Test conditions:
For this PR the "samples/basic/blinky" was used, overlay added to enable "standby" (PM3) and CONFIG_PM=y
CONFIG_PM_DEVICE=y added to the project config. The kernel uses the k_msleep(SLEEP_TIME_MS) code to enter into PM3. After this time expires the GPIO is reconfigured as output using the changes in this PR.

@matt-wood-ct
Copy link
Contributor

I just gave this a go on my frdm board with a current meter inserted on JP9 (IDD_MCU) and I'm seeing it alternating between 5.9 and 6.6mA, shouldn't it be around 100-200uA? Also the LED is not behaving correctly, it is just briefly flashing not the expected 50% on 50% off like the non PM sample.

@matt-wood-ct
Copy link
Contributor

Also tried turning off the LED and FLEXCOMM used for printf, currently only drops to ~5mA, something is seriously wrong with PM3 at the moment

@davidmissael
Copy link
Contributor Author

davidmissael commented May 6, 2025

Hello @matt-wood-ct one question:

  1. Are you enabling stand-by mode which represents PM3?
    It is expected the LED just to flash cause when entering PM3, the GPIOs loses state and clears, then when returning to application it turns on and then immediately clears cause the sleep instruction will put it into PM3 again. If you want to see the LED toggling, you need to add a delay to wait before entering into PM3.
    I will provide details on how I measure the current in my board.

@matt-wood-ct
Copy link
Contributor

Hello @matt-wood-ct one question:

  1. Are you enabling stand-by mode which represents PM3?
    It is expected the LED just to flash cause when entering PM3, the GPIOs loses state and clears, then when returning to application it turns on and then immediately clears cause the sleep instruction will put it into PM3 again. If you want to see the LED toggling, you need to add a delay to wait before entering into PM3.
    I will provide details on how I measure the current in my board.

Hi @davidmissael,

I do not think the MCU is falling over/crashing because I added a longer initial delay with busy wait (5 seconds) and I am not seeing that looping, so I believe it is retaining ram OK and resuming operation. I am using an overlay with standby status = okay and the delays are well over the 1000us required for standby (PM3) state.

@DerekSnell
Copy link
Collaborator

DerekSnell commented May 6, 2025

@matt-wood-ct FYI, by default, the RW61x SOC does not maintain the GPIO and pads state when the SOC enters PM3 mode. The state of these pads can be latched using the PAD_PWRDOWN_CTRL registers. The Zephyr GPIO APIs do not yet manage this. But applications can call IO_MUX_SetPinOutLevelInSleep() from the HAL_NXP to configure the states of the pads in PM3. Best regards

@davidmissael
Copy link
Contributor Author

davidmissael commented May 6, 2025

Hi @matt-wood-ct
We performed the current measurement on the RW612 FRDM board and we can confirm the current drops down below 1mA. The point you are taking your measurements very possible is not powering only the MCU, maybe there are some HW components powered while the MUC is entering into PM3. The best point for current measurement is removing the 0 ohms resistor "R103" and solder a couple of pins in JP5. DUT powers directly the MCU with minimum components involved:

image

image

@matt-wood-ct
Copy link
Contributor

Hi @matt-wood-ct We performed the current measurement on the RW612 FRDM board and we can confirm the current drops down below 1mA. The point you are taking your measurements very possible is not powering only the MCU, maybe there are some HW components powered while the MUC is entering into PM3. The best point for current measurement is removing the 0 ohms resistor "R103" and solder a couple of pins in JP5. DUT powers directly the MCU with minimum components involved:

Hi David,
Looking at the schematic this does not seem sensible, +3.3V_DUT appears to only go to rails on the RW612, it is not powering anything else on the board, additionally measuring only the input on vbat is not really meaningful in the context of low power single rail operation. Regardless I did try it out as you requested, the result I got was as follows:
With your branch I am ssing 750-1300uA current draw, still about 10x the expected figure. However when I tried the same on current NXP-zsdk, that did show 150-270uA, so the upstream changes are critical to achieving PM3 numbers.

The question remains though, if the current into Vbat is about right, then what is this extra 5mA going into the other power pins on the MCU? Is the radio on & leaking current? or is it going into Vio. So I took off R128 and measured across JP7. I can confirm that the current appears to be centred there as I measured 5.1-5.4mA on the connection.

Any suggestions which IO might be consuming this current, its pretty substantial.

@matt-wood-ct
Copy link
Contributor

@matt-wood-ct FYI, by default, the RW61x SOC does not maintain the GPIO and pads state when the SOC enters PM3 mode. The state of these pads can be latched using the PAD_PWRDOWN_CTRL registers. The Zephyr GPIO APIs do not yet manage this. But applications can call IO_MUX_SetPinOutLevelInSleep() from the HAL_NXP to configure the states of the pads in PM3. Best regards

Tested adding the snippet from the https://github.com/nxp-zephyr/hal_nxp/blob/5ed79a97220679f2fb862dceeb6484d88d9b49cc/mcux/mcux-sdk/boards/frdmrw612/board.c
into main and this made the LEDs turn on, naturally because IO 0,1 & 12 are low side LED drives, so I changed those to high and the VIO current went down to 1.6mA, I suspect a few other pins are being set to the wrong state during sleep. Still investigating.

@matt-wood-ct
Copy link
Contributor

matt-wood-ct commented May 7, 2025

Best result I ended up getting on Vio was with this snippet in main:

	for (i = 0; i < 64; i++)
	{
		IO_MUX_SetPinOutLevelInSleep(i, IO_MUX_SleepPinLevelLow);
	}

	for (i = 0; i < 4; i++)
	{
		IO_MUX_SetRfPinOutLevelInSleep(i, IO_MUX_SleepPinLevelLow);
	}

	/* LEDS */
	IO_MUX_SetPinOutLevelInSleep(0, IO_MUX_SleepPinLevelUnchanged);
	IO_MUX_SetPinOutLevelInSleep(1, IO_MUX_SleepPinLevelUnchanged);
	IO_MUX_SetPinOutLevelInSleep(12, IO_MUX_SleepPinLevelUnchanged);

	/* MDIO */
	IO_MUX_SetPinOutLevelInSleep(56, IO_MUX_SleepPinLevelHigh);
	IO_MUX_SetPinOutLevelInSleep(57, IO_MUX_SleepPinLevelHigh);

	/* I2C */
	IO_MUX_SetPinOutLevelInSleep(16, IO_MUX_SleepPinLevelHigh);
	IO_MUX_SetPinOutLevelInSleep(17, IO_MUX_SleepPinLevelHigh);

But this is still reading about 520uA into the Vio pins, so something is still leaking, I did a simple for loop toggling each sleep level on each pin and was not able to find the cause, so maybe it isn't a pin directly.

ps. when measured on the main IDD_MCU header (JP9) this now shows the overall current as 810uA.

@davidmissael
Copy link
Contributor Author

GPIO issue was implemented in:
#89905
This draft won't be needed anymore. Proceed to close

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: GPIO platform: NXP Drivers NXP Semiconductors, drivers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants