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.

  • 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

  • Hi Berg.

    I have verified your source code.
    It's okay.

    When I cross-test my source code,
    I found that when I declared the relevant information of BT in your prj.conf,
    I just added the following declaration to prj.conf,

    I did not add any description to any C code.
    At this time the system will wake up.

    We have a test item that is doing broadcast and connection testing.
    So I need to add BT function in radio_test.

Related