samples: mimxrt595: Add Deep power down sample
Add a sample to put the part into Deep power down mode by setting the state to PM_STATE_SOFT_OFF. Wakup the part using an RTC alarm. Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
This commit is contained in:
parent
3f38b011c3
commit
1a27e2bd8e
7 changed files with 263 additions and 0 deletions
|
@ -0,0 +1,9 @@
|
||||||
|
# Copyright 2022, NXP
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
project(mimxrt595_evk_cm33_system_off)
|
||||||
|
|
||||||
|
target_sources(app PRIVATE src/main.c)
|
7
samples/boards/mimxrt595_evk_cm33/system_off/Kconfig
Normal file
7
samples/boards/mimxrt595_evk_cm33/system_off/Kconfig
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# Copyright 2022, NXP
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
mainmenu "MIMXRT595_EVK_CM33 SYSTEM_OFF demo"
|
||||||
|
|
||||||
|
source "Kconfig.zephyr"
|
142
samples/boards/mimxrt595_evk_cm33/system_off/README.rst
Normal file
142
samples/boards/mimxrt595_evk_cm33/system_off/README.rst
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
.. _mimxrt595_evk-system-off-sample:
|
||||||
|
|
||||||
|
RT595 System Off demo
|
||||||
|
#####################
|
||||||
|
|
||||||
|
Overview
|
||||||
|
********
|
||||||
|
|
||||||
|
This sample can be used for basic power measurement and as an example of
|
||||||
|
soft off on NXP i.MX RT platforms. The functional behavior is:
|
||||||
|
|
||||||
|
* Busy-wait for 2 seconds
|
||||||
|
* Turn the system off after enabling wakeup through RTC and set alarm
|
||||||
|
10 seconds in the future to wake up the processor
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
************
|
||||||
|
|
||||||
|
This application uses MIMXRT595-EVK for the demo.
|
||||||
|
|
||||||
|
Building, Flashing and Running
|
||||||
|
******************************
|
||||||
|
|
||||||
|
.. zephyr-app-commands::
|
||||||
|
:zephyr-app: samples/boards/mimxrt595_evk_cm33/system_off
|
||||||
|
:board: mimxrt595_evk_cm33
|
||||||
|
:goals: build flash
|
||||||
|
:compact:
|
||||||
|
|
||||||
|
Running:
|
||||||
|
|
||||||
|
1. Open UART terminal.
|
||||||
|
2. Power Cycle Device.
|
||||||
|
3. Device will turn on and idle for 2 seconds
|
||||||
|
4. Device will turn itself off using deep power down mode. RTC alarm
|
||||||
|
will wake device and restart the application from a warm reset.
|
||||||
|
|
||||||
|
Sample Output
|
||||||
|
=================
|
||||||
|
MIMXRT595-EVK core output
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
*** Booting Zephyr OS build zephyr-v3.2.0-1045-g07228f716c78 ***
|
||||||
|
|
||||||
|
mimxrt595_evk_cm33 system off demo
|
||||||
|
RTC Alarm set for 10 seconds to wake from soft-off.
|
||||||
|
Entering system off
|
||||||
|
|
||||||
|
OTP Fuse setting to wake from Deep Power Down and reset flash
|
||||||
|
#############################################################
|
||||||
|
|
||||||
|
Background
|
||||||
|
**********
|
||||||
|
|
||||||
|
This sample will not resume the application after waking from Deep Power
|
||||||
|
Down (DPD) mode on an EVK with default settings. The reason is that the
|
||||||
|
flash is not normally reset when waking from DPD. This sample
|
||||||
|
eXecutes-In-Place (XIP) from the external flash. When the MCU wakes from
|
||||||
|
DPD, it wakes through the reset flow. But if the external flash is not
|
||||||
|
reset, the MCU and flash are no longer in sync, and the MCU cannot XIP.
|
||||||
|
In this default state, one can confirm the RTC is waking the MCU from
|
||||||
|
DPD because the MCU will set the PMIC_MODE pins to 0b00 requesting the
|
||||||
|
PMIC to enter the default boot mode, and the PMIC will enable the
|
||||||
|
regulator driving the VDDCORE rail at 1.0V. However, the MCU will not be
|
||||||
|
able to XIP from the flash to resume. One can press the Reset button in
|
||||||
|
this state to restart the app.
|
||||||
|
|
||||||
|
To wake from DPD and resume XIP from the flash, the MCU needs to be
|
||||||
|
configured to reset the external flash. This can be done by programming
|
||||||
|
the One-Time-Programmable (OTP) fuses in the MCU. The steps below detail
|
||||||
|
how program the OTP BOOT_CFG1 fuses to use GPIO pin PIO4_5 as the flash
|
||||||
|
reset. This fuse setting instructs the ROM bootloader to toggle PIO4_5
|
||||||
|
when resetting the flash. Note that the MIMXRT595-EVK board is designed
|
||||||
|
to have PIO4_5 drive the octal flash reset pin on FlexSPI0. Other boards
|
||||||
|
using this MCU may use a different GPIO pin, and the setting in the OTP
|
||||||
|
fuses must match the GPIO pin connected to reset. Before programming
|
||||||
|
fuses, it is best to write the OTP shadow registers first and confirm
|
||||||
|
the operation. Then program the OTP fuses after confirming the correct
|
||||||
|
settings. For more details on OTP fuses and shadow registers, refer to
|
||||||
|
the Reference Manual for this MCU, and the OTP Fuse Map spreadsheet
|
||||||
|
included as an attachment in the Reference Manual PDF.
|
||||||
|
|
||||||
|
Tools needed
|
||||||
|
************
|
||||||
|
These steps use the blhost tool that runs on a host computer running
|
||||||
|
Linux, Windows, or MacOS. Download blhost, find the appropriate blhost
|
||||||
|
executable for your host OS, and use the command-line steps below to
|
||||||
|
program the OTP fuses. To download, go to https://www.nxp.com/mcuboot,
|
||||||
|
and find the Blhost package under Downloads.
|
||||||
|
|
||||||
|
Steps to program OTP fuses on MIMXRT595-EVK
|
||||||
|
*******************************************
|
||||||
|
These steps detail using USB as the interface between blhost and the
|
||||||
|
ROM bootloader. UART is another option, for more details see the
|
||||||
|
blhost documentation and the Boot ROM chapter in the MCU Reference
|
||||||
|
Manual.
|
||||||
|
|
||||||
|
1. Power the EVK and connect USB J38 to host computer. J38 is for the
|
||||||
|
USB peripheral of the MCU, and will also power the EVK.
|
||||||
|
|
||||||
|
2. Set the DIP switches of SW7 to On-Off-On (123) to boot in ISP USB
|
||||||
|
HID mode.
|
||||||
|
|
||||||
|
3. Press the Reset button SW3 to boot in ISP mode. The EVK should
|
||||||
|
enumerate as a USB HID device in the host computer.
|
||||||
|
|
||||||
|
4. This command confirms the current settings of BOOT_CFG1 fuses:
|
||||||
|
blhost -u 0x1fc9,0x0023 -- efuse-read-once 0x61
|
||||||
|
|
||||||
|
5. This command programs BOOT_CFG1 to enable the flash reset pin using
|
||||||
|
PIO4_5:
|
||||||
|
blhost -u 0x1fc9,0x0023 -- efuse-program-once 0x61 0x164000
|
||||||
|
|
||||||
|
6. This command confirms the programmed fuses in BOOT_CFG1:
|
||||||
|
blhost -u 0x1fc9,0x0023 -- efuse-read-once 0x61
|
||||||
|
|
||||||
|
7. Set the DIP switches of SW7 to Off-Off-On (123) to boot from the
|
||||||
|
external flash on FlexSPI0.
|
||||||
|
|
||||||
|
8. Press the Reset button SW3 to boot from flash and run the app.
|
||||||
|
|
||||||
|
Expected results from blhost
|
||||||
|
****************************
|
||||||
|
|
||||||
|
>blhost -u 0x1fc9,0x0023 -- efuse-read-once 0x61
|
||||||
|
Inject command 'efuse-read-once'
|
||||||
|
Response status = 0 (0x0) Success.
|
||||||
|
Response word 1 = 4 (0x4)
|
||||||
|
Response word 2 = 0 (0x0)
|
||||||
|
|
||||||
|
>blhost -u 0x1fc9,0x0023 -- efuse-program-once 0x61 0x164000
|
||||||
|
Inject command 'efuse-program-once'
|
||||||
|
Successful generic response to command 'efuse-program-once'
|
||||||
|
Response status = 0 (0x0) Success.
|
||||||
|
|
||||||
|
>blhost -u 0x1fc9,0x0023 -- efuse-read-once 0x61
|
||||||
|
Inject command 'efuse-read-once'
|
||||||
|
Response status = 0 (0x0) Success.
|
||||||
|
Response word 1 = 4 (0x4)
|
||||||
|
Response word 2 = 1458176 (0x164000)
|
10
samples/boards/mimxrt595_evk_cm33/system_off/app.overlay
Normal file
10
samples/boards/mimxrt595_evk_cm33/system_off/app.overlay
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022, NXP
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
&rtc {
|
||||||
|
status = "okay";
|
||||||
|
wakeup-source;
|
||||||
|
};
|
14
samples/boards/mimxrt595_evk_cm33/system_off/prj.conf
Normal file
14
samples/boards/mimxrt595_evk_cm33/system_off/prj.conf
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#
|
||||||
|
# Copyright 2022, NXP
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
CONFIG_PM=y
|
||||||
|
|
||||||
|
# Turn on Device Level Power Management as we wish
|
||||||
|
# to reconfigure the FlexSPI pins for power savings
|
||||||
|
# when transitioning the SoC to Deep Low Power modes.
|
||||||
|
CONFIG_PM_DEVICE=y
|
||||||
|
|
||||||
|
# Enable the RTC
|
||||||
|
CONFIG_COUNTER=y
|
13
samples/boards/mimxrt595_evk_cm33/system_off/sample.yaml
Normal file
13
samples/boards/mimxrt595_evk_cm33/system_off/sample.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#
|
||||||
|
# Copyright 2022, NXP
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
sample:
|
||||||
|
name: Deep Power Down State Sample for mimxrt595_evk
|
||||||
|
common:
|
||||||
|
tags: power
|
||||||
|
tests:
|
||||||
|
sample.boards.mimxrt595_evk_cm33.system_off:
|
||||||
|
build_only: true
|
||||||
|
platform_allow: mimxrt595_evk_cm33
|
68
samples/boards/mimxrt595_evk_cm33/system_off/src/main.c
Normal file
68
samples/boards/mimxrt595_evk_cm33/system_off/src/main.c
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022, NXP
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/drivers/gpio.h>
|
||||||
|
#include <zephyr/drivers/counter.h>
|
||||||
|
#include <zephyr/pm/pm.h>
|
||||||
|
#include <zephyr/pm/policy.h>
|
||||||
|
|
||||||
|
#define BUSY_WAIT_S 2U
|
||||||
|
#define SLEEP_S 2U
|
||||||
|
#define SOFT_OFF_S 10U
|
||||||
|
|
||||||
|
#define RTC_NODE DT_NODELABEL(rtc)
|
||||||
|
#if !DT_NODE_HAS_STATUS(RTC_NODE, okay)
|
||||||
|
#error "Unsupported board: rtc node is not enabled"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RTC_CHANNEL_ID 0
|
||||||
|
|
||||||
|
static const struct device *const rtc_dev = DEVICE_DT_GET(RTC_NODE);
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
printk("\n%s system off demo\n", CONFIG_BOARD);
|
||||||
|
|
||||||
|
uint32_t sleep_ticks = counter_us_to_ticks(rtc_dev, SOFT_OFF_S * 1000ULL * 1000ULL);
|
||||||
|
|
||||||
|
counter_start(rtc_dev);
|
||||||
|
|
||||||
|
if (sleep_ticks == 0) {
|
||||||
|
/* counter_us_to_ticks will round down the number of ticks to the nearest int. */
|
||||||
|
/* Ensure at least one tick is used in the RTC */
|
||||||
|
sleep_ticks++;
|
||||||
|
}
|
||||||
|
const struct counter_alarm_cfg alarm_cfg = {
|
||||||
|
.ticks = sleep_ticks,
|
||||||
|
.flags = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = counter_set_channel_alarm(rtc_dev, RTC_CHANNEL_ID, &alarm_cfg);
|
||||||
|
if (ret != 0) {
|
||||||
|
printk("Could not rtc alarm.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printk("RTC Alarm set for %llu seconds to wake from soft-off.\n",
|
||||||
|
counter_ticks_to_us(rtc_dev, alarm_cfg.ticks) / (1000ULL * 1000ULL));
|
||||||
|
printk("Entering system off");
|
||||||
|
|
||||||
|
pm_state_force(0u, &(struct pm_state_info){ PM_STATE_SOFT_OFF, 0, 0 });
|
||||||
|
|
||||||
|
/* Now we need to go sleep. This will let the idle thread runs and
|
||||||
|
* the pm subsystem will use the forced state.
|
||||||
|
*/
|
||||||
|
k_sleep(K_SECONDS(SLEEP_S));
|
||||||
|
|
||||||
|
printk("ERROR: System off failed\n");
|
||||||
|
while (true) {
|
||||||
|
/* spin to avoid fall-off behavior */
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue