samples: nrf52: replace power_mgr with system_off

The Nordic SOC doesn't support multiple system power states, only one
deep sleep state.  Replace the old example with a simpler one that can
be used to measure CPU active, normal sleep, and system off modes.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2019-11-18 18:08:08 -06:00 committed by Anas Nashif
commit e83b079e22
13 changed files with 123 additions and 401 deletions

View file

@ -1,13 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
config NRF5_POWER_MGMT_EXAMPLE
bool
default y
select HAS_SYS_POWER_STATE_SLEEP_2
select HAS_SYS_POWER_STATE_SLEEP_3
help
Hidden option enabling LPS_1 and LPS_2 low power states.
This is needed, as these states are implemented by this example.
# Include Zephyr's Kconfig.
source "$ZEPHYR_BASE/Kconfig"

View file

@ -1,112 +0,0 @@
.. _nrf5x-power-mgr-sample:
nRF5x Power management demo
###########################
Overview
********
This sample demonstrates a power manager app that uses the Zephyr
power management infrastructure to enter into Low Power state.
This app will cycle through the following power schemes each time the system
enters idle state:
1. Low Power State: Low Power State could be SoC, board and/or application
specific. Being in this state is transparent to devices. SOC and devices
do not lose context in this Mode. This example implements two Low Power
states, which are signaled using LEDs on the development kit:
A. LED1: [X], LED2: [X]: System is active, no low power state is selected.
B. LED1: [X], LED2: [ ]: System is idle, and the SYS_POWER_STATE_SLEEP_2
state is selected.
C. LED1: [ ], LED2: [ ]: System is idle, and the SYS_POWER_STATE_SLEEP_3
state is selected.
2. Deep Sleep: This Power State is mapped to SYSTEM OFF state. In this mode
all devices on board get suspended. All devices and SOC lose context on
wake up.
The power mode selection is done automatically by residency-based policy
implemented by the Zephyr Power Management Subsystem.
Requirements
************
This application uses nRF51 DK or nRF52 DK board for the demo.
Building, Flashing and Running
******************************
.. zephyr-app-commands::
:zephyr-app: samples/boards/nrf/power_mgr
:board: nrf52_pca10040
:goals: build flash
:compact:
Running:
1. Open UART terminal.
2. Power Cycle Device.
3. Device will enter into Low Power Modes.
4. Press Button 1 on device to enter deep sleep state.
5. Press Button 2 on device to wake up from deep sleep state.
Sample Output
=================
nRF52 core output
-----------------
.. code-block:: console
*** Power Management Demo on nrf52_pca10040 ***
Demo Description
Application creates idleness, due to which System Idle Thread is
scheduled and it enters into various Low Power States.
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 10 Sec -->
--> Entering to SYS_POWER_STATE_SLEEP_2 state.
--> Exited from SYS_POWER_STATE_SLEEP_2 state.
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 30 Sec -->
--> Entering to SYS_POWER_STATE_SLEEP_3 state.
--> Exited from SYS_POWER_STATE_SLEEP_3 state.
<-- Disabling SYS_POWER_STATE_SLEEP_3 state --->
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 10 Sec -->
--> Entering to SYS_POWER_STATE_SLEEP_2 state.
--> Exited from SYS_POWER_STATE_SLEEP_2 state.
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 30 Sec -->
--> Entering to SYS_POWER_STATE_SLEEP_2 state.
--> Exited from SYS_POWER_STATE_SLEEP_2 state.
<-- Enabling SYS_POWER_STATE_SLEEP_3 state --->
<-- Disabling SYS_POWER_STATE_SLEEP_2 state --->
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 10 Sec -->
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 30 Sec -->
--> Entering to SYS_POWER_STATE_SLEEP_3 state.
--> Exited from SYS_POWER_STATE_SLEEP_3 state.
<-- Enabling SYS_POWER_STATE_SLEEP_2 state --->
<-- Forcing SYS_POWER_STATE_SLEEP_3 state --->
<-- App doing busy wait for 10 Sec -->
<-- App going to sleep for 10 Sec -->

View file

@ -1,10 +0,0 @@
CONFIG_BT=n
CONFIG_TIMESLICING=n
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_SLEEP_STATES=y
CONFIG_SYS_POWER_DEEP_SLEEP_STATES=y
CONFIG_DEVICE_POWER_MANAGEMENT=y
CONFIG_SYS_PM_STATE_LOCK=y
CONFIG_SYS_PM_MIN_RESIDENCY_SLEEP_1=5000
CONFIG_SYS_PM_MIN_RESIDENCY_SLEEP_2=15000
CONFIG_GPIO=y

View file

@ -1,12 +0,0 @@
CONFIG_NUM_COOP_PRIORITIES=29
CONFIG_NUM_PREEMPT_PRIORITIES=40
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_SLEEP_STATES=y
CONFIG_SYS_POWER_DEEP_SLEEP_STATES=y
CONFIG_DEVICE_POWER_MANAGEMENT=y
CONFIG_TICKLESS_KERNEL=y
CONFIG_PM_CONTROL_OS=y
CONFIG_PM_CONTROL_STATE_LOCK=y
CONFIG_PM_LPS_1_MIN_RES=5
CONFIG_PM_LPS_2_MIN_RES=15
CONFIG_GPIO=y

View file

@ -1,15 +0,0 @@
sample:
name: Low Power State Sample for nRF5x
tests:
sample.board.nrf52.pm.low_power_state:
platform_whitelist: nrf52840_pca10056 nrf52_pca10040 nrf51_pca10028
timeout: 150
tags: power
harness: console
harness_config:
type: multi_line
regex:
- "--> Entering to SYS_POWER_STATE_SLEEP_3 state."
- "--> Exited from SYS_POWER_STATE_SLEEP_3 state."
- "--> Entering to SYS_POWER_STATE_SLEEP_2 state."
- "--> Exited from SYS_POWER_STATE_SLEEP_2 state."

View file

@ -1,114 +0,0 @@
/*
* Copyright (c) 2016 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sample.h"
#define BUSY_WAIT_DELAY_US (10 * 1000000)
#define LPS1_STATE_ENTER_TO 10
#define LPS2_STATE_ENTER_TO 30
#define DEEP_SLEEP_STATE_ENTER_TO 90
#define DEMO_DESCRIPTION \
"Demo Description\n" \
"Application creates idleness, due to which System Idle Thread is\n"\
"scheduled and it enters into various Low Power States.\n"\
struct device *gpio_port;
/* Application main Thread */
void main(void)
{
u32_t level = 0U;
printk("\n\n*** Power Management Demo on %s ***\n", CONFIG_BOARD);
printk(DEMO_DESCRIPTION);
gpio_port = device_get_binding(PORT);
/* Configure Button 1 as deep sleep trigger event */
gpio_pin_configure(gpio_port, BUTTON_1, GPIO_DIR_IN
| GPIO_PUD_PULL_UP);
/* Configure Button 2 as wake source from deep sleep */
gpio_pin_configure(gpio_port, BUTTON_2, GPIO_DIR_IN
| GPIO_PUD_PULL_UP
| GPIO_INT | GPIO_INT_LEVEL
| GPIO_CFG_SENSE_LOW);
gpio_pin_enable_callback(gpio_port, BUTTON_2);
/* Configure LEDs */
gpio_pin_configure(gpio_port, LED_1, GPIO_DIR_OUT);
gpio_pin_write(gpio_port, LED_1, LED_ON);
gpio_pin_configure(gpio_port, LED_2, GPIO_DIR_OUT);
gpio_pin_write(gpio_port, LED_2, LED_ON);
/*
* Start the demo.
*/
for (int i = 1; i <= 8; i++) {
unsigned int sleep_seconds;
switch (i) {
case 3:
printk("\n<-- Disabling %s state --->\n",
STRINGIFY(SYS_POWER_STATE_SLEEP_3));
sys_pm_ctrl_disable_state(SYS_POWER_STATE_SLEEP_3);
break;
case 5:
printk("\n<-- Enabling %s state --->\n",
STRINGIFY(SYS_POWER_STATE_SLEEP_3));
sys_pm_ctrl_enable_state(SYS_POWER_STATE_SLEEP_3);
printk("<-- Disabling %s state --->\n",
STRINGIFY(SYS_POWER_STATE_SLEEP_2));
sys_pm_ctrl_disable_state(SYS_POWER_STATE_SLEEP_2);
break;
case 7:
printk("\n<-- Enabling %s state --->\n",
STRINGIFY(SYS_POWER_STATE_SLEEP_2));
sys_pm_ctrl_enable_state(SYS_POWER_STATE_SLEEP_2);
printk("<-- Forcing %s state --->\n",
STRINGIFY(SYS_POWER_STATE_SLEEP_3));
sys_pm_force_power_state(SYS_POWER_STATE_SLEEP_3);
break;
default:
/* Do nothing. */
break;
}
printk("\n<-- App doing busy wait for 10 Sec -->\n");
k_busy_wait(BUSY_WAIT_DELAY_US);
sleep_seconds = (i % 2 != 0) ? LPS1_STATE_ENTER_TO :
LPS2_STATE_ENTER_TO;
printk("\n<-- App going to sleep for %u Sec -->\n",
sleep_seconds);
k_sleep(K_SECONDS(sleep_seconds));
}
/* Restore automatic power management. */
printk("\n<-- Forcing %s state --->\n",
STRINGIFY(SYS_POWER_STATE_AUTO));
sys_pm_force_power_state(SYS_POWER_STATE_AUTO);
printk("\nPress BUTTON1 to enter into Deep Sleep state. "
"Press BUTTON2 to exit Deep Sleep state\n");
while (1) {
gpio_pin_read(gpio_port, BUTTON_1, &level);
if (level == LOW) {
k_sleep(K_SECONDS(DEEP_SLEEP_STATE_ENTER_TO));
}
k_busy_wait(1000);
}
}

View file

@ -1,95 +0,0 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sample.h"
/*
* Application defined function for doing any target specific operations
* for low power entry.
*/
void sys_pm_notify_power_state_entry(enum power_states state)
{
switch (state) {
case SYS_POWER_STATE_SLEEP_2:
printk("--> Entering to SYS_POWER_STATE_SLEEP_2 state.\n");
/*
* This power state is implemented by this sample.
* Perform enter to the low power state by turning off LED2.
*/
gpio_pin_write(gpio_port, LED_1, LED_ON);
gpio_pin_write(gpio_port, LED_2, LED_OFF);
k_cpu_idle();
break;
case SYS_POWER_STATE_SLEEP_3:
printk("--> Entering to SYS_POWER_STATE_SLEEP_3 state.\n");
/*
* This power state is implemented by this sample.
* Perform enter to the low power state by turning off LEDs.
*/
gpio_pin_write(gpio_port, LED_1, LED_OFF);
gpio_pin_write(gpio_port, LED_2, LED_OFF);
k_cpu_idle();
break;
case SYS_POWER_STATE_DEEP_SLEEP_1:
printk("--> Entering to SYS_POWER_STATE_DEEP_SLEEP_1 state.\n");
/*
* This power mode is already implemented by the OS. It will be
* handled by SoC-specific code. Here we just turn off the LEDs
* to save power.
*/
gpio_pin_write(gpio_port, LED_1, LED_OFF);
gpio_pin_write(gpio_port, LED_2, LED_OFF);
/* Nothing else to do */
break;
default:
printk("Unsupported power state %u", state);
break;
}
}
/*
* Application defined function for doing any target specific operations
* for low power exit.
*/
void sys_pm_notify_power_state_exit(enum power_states state)
{
switch (state) {
case SYS_POWER_STATE_SLEEP_2:
printk("--> Exited from SYS_POWER_STATE_SLEEP_2 state.\n");
/* Perform exit from the low power state by turning on LEDs */
gpio_pin_write(gpio_port, LED_1, LED_ON);
gpio_pin_write(gpio_port, LED_2, LED_ON);
break;
case SYS_POWER_STATE_SLEEP_3:
printk("--> Exited from SYS_POWER_STATE_SLEEP_3 state.\n");
/* Perform exit from the low power state by turning on LEDs */
gpio_pin_write(gpio_port, LED_1, LED_ON);
gpio_pin_write(gpio_port, LED_2, LED_ON);
break;
case SYS_POWER_STATE_DEEP_SLEEP_1:
printk("--> Exited from SYS_POWER_STATE_DEEP_SLEEP_1 state.\n");
/* Turn on LEDs which were powered down before deep sleep. */
gpio_pin_write(gpio_port, LED_1, LED_ON);
gpio_pin_write(gpio_port, LED_2, LED_ON);
break;
default:
printk("Unsupported power state %u", state);
break;
}
}

View file

@ -1,29 +0,0 @@
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <power/power.h>
#include <string.h>
#include <soc.h>
#include <device.h>
#include <drivers/gpio.h>
#include <sys/printk.h>
#define GPIO_CFG_SENSE_LOW (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos)
/* change this to use another GPIO port */
#define PORT DT_ALIAS_SW0_GPIOS_CONTROLLER
#define BUTTON_1 DT_ALIAS_SW0_GPIOS_PIN
#define BUTTON_2 DT_ALIAS_SW1_GPIOS_PIN
#define LED_1 DT_ALIAS_LED0_GPIOS_PIN
#define LED_2 DT_ALIAS_LED1_GPIOS_PIN
#define LOW 0
#define HIGH 1
#define LED_ON LOW
#define LED_OFF HIGH
extern struct device *gpio_port;

View file

@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(nrf52_power_mgr)
project(nrf_system_off)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,57 @@
.. _nrf-system-off-sample:
nRF5x System Off demo
#####################
Overview
********
This sample can be used for basic power measurement and as an example of
deep sleep on Nordic platforms. The functional behavior is:
* Busy-wait for 2 seconds
* Sleep for 2 seconds
* Sleep for a duration that would, by policy, cause the system to power
off if the deep sleep state was not disabled
* Turn the system off after enabling wakeup through a button press
A power monitor will be able to distinguish among these states.
Requirements
************
This application uses nRF51 DK or nRF52 DK board for the demo.
Building, Flashing and Running
******************************
.. zephyr-app-commands::
:zephyr-app: samples/boards/nrf52/system_off
:board: nrf52_pca10040
:goals: build flash
:compact:
Running:
1. Open UART terminal.
2. Power Cycle Device.
3. Device will demonstrate two activity levels which can be measured.
4. Device will demonstrate long sleep at minimal non-off power.
5. Device will turn itself off using deep sleep state 1. Press Button 1
to wake the device and restart the application as if it had been
powered back on.
Sample Output
=================
nRF52 core output
-----------------
.. code-block:: console
***** Booting Zephyr OS build v2.1.0-rc1-158-gb642e1a96d17 *****
nrf52_pca10040 system off demo
Busy-wait 2 s
Sleep 2 s
Sleep 60000 ms (deep sleep minimum)
Entering system off; press BUTTON1 to restart

View file

@ -0,0 +1,5 @@
CONFIG_SYS_POWER_MANAGEMENT=y
CONFIG_SYS_POWER_DEEP_SLEEP_STATES=y
# Required to disable default behavior of deep sleep on timeout
CONFIG_SYS_PM_STATE_LOCK=y
CONFIG_GPIO=y

View file

@ -0,0 +1,7 @@
sample:
name: Low Power State Sample for nRF5x
tests:
sample.boards.nrf.system_off:
build_only: true
platform_whitelist: nrf52840_pca10056 nrf52_pca10040 nrf51_pca10028
tags: power

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <zephyr.h>
#include <power/power.h>
#include <hal/nrf_gpio.h>
#define BUSY_WAIT_S 2U
#define SLEEP_S 2U
void main(void)
{
printk("\n%s system off demo\n", CONFIG_BOARD);
/* Configure to generate PORT event (wakeup) on button 1 press. */
nrf_gpio_cfg_input(DT_GPIO_KEYS_BUTTON_0_GPIOS_PIN,
NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_sense_set(DT_GPIO_KEYS_BUTTON_0_GPIOS_PIN,
NRF_GPIO_PIN_SENSE_LOW);
/* Prevent deep sleep (system off) from being entered on long
* timeouts.
*/
sys_pm_ctrl_disable_state(SYS_POWER_STATE_DEEP_SLEEP_1);
printk("Busy-wait %u s\n", BUSY_WAIT_S);
k_busy_wait(BUSY_WAIT_S * USEC_PER_SEC);
printk("Sleep %u s\n", SLEEP_S);
k_sleep(K_SECONDS(SLEEP_S));
printk("Sleep %u ms (deep sleep minimum)\n",
CONFIG_SYS_PM_MIN_RESIDENCY_DEEP_SLEEP_1);
k_sleep(K_MSEC(CONFIG_SYS_PM_MIN_RESIDENCY_DEEP_SLEEP_1));
printk("Entering system off; press BUTTON1 to restart\n");
/* Above we disabled entry to deep sleep based on duration of
* controlled delay. Here we need to override that, then
* force a sleep so that the deep sleep takes effect.
*/
sys_pm_force_power_state(SYS_POWER_STATE_DEEP_SLEEP_1);
k_sleep(K_MSEC(1));
printk("ERROR: System off failed\n");
while (true) {
/* spin to avoid fall-off behavior */
}
}