Add a UART command in radio_test to enter sleep mode

Dear nRF experts.
We use the sample code of radio_test as the production test program. We directly add a UART command. When the user enters this command, it will enter sleep mode. However, we found that once it enters sleep mode, it will restart immediately.
My program is as follows.

static int cmd_bjja_lm_sleep(const struct shell *shell, size_t argc,
				 char **argv)
{
	radio_test_cancel();
	bt_disable();
	shell_print(shell, "entry to sleep mode\r\n");
	//sleep test
	NRF_MEMCONF->POWER[0].RET = 0;
	NRF_MEMCONF->POWER[1].RET = 0;
	NRF_MEMCONF->POWER[0].RET2 = 0;
	NRF_MEMCONF->POWER[1].RET2 = 0;
	sys_poweroff();
}
SHELL_CMD_REGISTER(cansec_sleep_test, NULL,
		   "entry sleep for measure current consumption.",
		    cmd_bjja_lm_sleep);

Do I need to disable any functions before power_off?
If I use the Power_off sample code, it works then everything is OK.

Parents Reply Children
  • Hi,

    Have you confirmed through debugging that the device is actually entering System OFF before waking up again and not just resetting due to a runtime error while attempting to enter this mode?

    Print reset reason on startuo:

    https://github.com/nrfconnect/sdk-nrf/blob/45a51fc620ef52421106c7cf4c8eb0f80b2fddcf/samples/bluetooth/peripheral_power_profiling/src/main.c#L593 

  • Hi Berg.

    i have add boot reason function.

    it show below message.

    when I send sleep command via uart into sleep.

    System reset from different reason 0x00000800

  • Hi,

    Wakeup is apparently triggered by the GRTC. As a test, please try to stop the GRTC before entering System OFF:

    #include "nrf.h"
    
    ...
    
    NRF_GRTC->TASKS_STOP=1;
    
    sysoff();
     
     

  • Hi Berg,

    I'm sorry to reply to you so late, we have the Lunar New Year holiday until this Wednesday, I just tried the solution you provided, but it still wakes up, below is my source code and the result.

    Is there something I overlooked?

  • Happy new year! Could you please try the demo sample below with SDK v2.9.0 and see if you get the the same result? The GRTC did not trigger any wakeups in my tests.

    radio_test_system_off_test.zip

    Changes:

    diff --git a/prj.conf b/prj.conf
    index c130dc5..334a8f1 100644
    --- a/prj.conf
    +++ b/prj.conf
    @@ -17,3 +17,6 @@ CONFIG_NRF_SECURITY=y
     
     CONFIG_FEM_AL_LIB=y
     CONFIG_PICOLIBC_IO_FLOAT=y
    +
    +CONFIG_POWEROFF=y
    +CONFIG_PM_DEVICE=y
    diff --git a/src/main.c b/src/main.c
    index c5a4983..eb753fa 100644
    --- a/src/main.c
    +++ b/src/main.c
    @@ -4,6 +4,7 @@
      * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
      */
     
    +#include <helpers/nrfx_reset_reason.h>
     #include <zephyr/sys/printk.h>
     #include <zephyr/drivers/clock_control.h>
     #include <zephyr/drivers/clock_control/nrf_clock_control.h>
    @@ -89,9 +90,38 @@ static void clock_init(void)
     BUILD_ASSERT(false, "No Clock Control driver");
     #endif /* defined(CONFIG_CLOCK_CONTROL_NRF) */
     
    +static void reset_reason_print(void)
    +{
    +	uint32_t reason;
    +
    +	reason = nrfx_reset_reason_get();
    +
    +	if (reason & NRFX_RESET_REASON_NFC_MASK) {
    +		printk("Wake up by NFC field detected\n");
    +	} else if (reason & NRFX_RESET_REASON_OFF_MASK) {
    +		printk("Wake up by the advertising start buttons\n");
    +/* Workaround for typo in the NRFX. */
    +#if !NRF_POWER_HAS_RESETREAS
    +	} else if (reason & NRFX_RESET_REASON_SREQ_MASK) {
    +#else
    +	} else if (reason & NRFX_RESET_REASON_SREQ_MASK) {
    +#endif
    +		printk("Application soft reset detected\n");
    +	} else if (reason & NRFX_RESET_REASON_RESETPIN_MASK) {
    +		printk("Reset from pin-reset\n");
    +	} else if (reason) {
    +		printk("System reset from different reason 0x%08X\n", reason);
    +	} else {
    +		printk("Power-on reset\n");
    +	}
    +}
    +
     int main(void)
     {
     	printk("Starting Radio Test example\n");
    +	reset_reason_print();
    +	/* Clear RESETREAS register */
    +	nrfx_reset_reason_clear(nrfx_reset_reason_get());
     
     	clock_init();
     
    diff --git a/src/radio_cmd.c b/src/radio_cmd.c
    index cd2659a..e63442f 100644
    --- a/src/radio_cmd.c
    +++ b/src/radio_cmd.c
    @@ -7,6 +7,9 @@
     #include <stdlib.h>
     
     #include <errno.h>
    +#include <zephyr/pm/device.h>
    +#include <zephyr/device.h>
    +#include <zephyr/sys/poweroff.h>
     #include <zephyr/init.h>
     #include <zephyr/shell/shell.h>
     #include <zephyr/types.h>
    @@ -1158,6 +1161,17 @@ static int cmd_print_payload(const struct shell *shell, size_t argc,
     
     	return 0;
     }
    +static const struct device *uart_dev = DEVICE_DT_GET_ANY(nordic_nrf_uarte);
    +
    +static int cmd_enter_sleep(const struct shell *shell, size_t argc,
    +			     char **argv)
    +{
    +	radio_test_cancel();
    +	(void) pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND);
    +
    +	sys_poweroff();
    +	return 0;
    +}
     
     #if CONFIG_FEM
     static int cmd_fem(const struct shell *shell, size_t argc, char **argv)
    @@ -1471,6 +1485,7 @@ SHELL_CMD_REGISTER(start_rx_sweep, NULL, "Start RX sweep", cmd_rx_sweep_start);
     SHELL_CMD_REGISTER(start_tx_sweep, NULL, "Start TX sweep", cmd_tx_sweep_start);
     SHELL_CMD_REGISTER(start_rx, NULL, "Start RX", cmd_rx_start);
     SHELL_CMD_REGISTER(print_rx, NULL, "Print RX payload", cmd_print_payload);
    +SHELL_CMD_REGISTER(enter_sleep, NULL, "Enter System OFF mode", cmd_enter_sleep);
     #if defined(TOGGLE_DCDC_HELP)
     SHELL_CMD_REGISTER(toggle_dcdc_state, NULL, TOGGLE_DCDC_HELP, cmd_toggle_dc);
     #endif

Related