This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Problem with waking-up via Timer interrupt or Serial periph.

Hi, I have a problem with waking up a device, description as below.

Application description:
I made some application which is based on Serial example - all is working fine till I want to add low power mode functionality.

The application logic looks that nRF52840-DK is talking with a modem (AT commands) via Serial port and each i.e. 2 minutes is sending data to the server. Timer and Serial interrupts are working with Scheduler, application without low power mode are working fine but there is a need to apply low power mode because the device will work from battery. Regarding PWR_MGMT example I try to add "low power mode" functionality to my application. Unfortunately, the application doesn't want to wake up after going to sleep mode.

Problem description:
I have no idea about power mode on NRF so I took "pwr_mgmt/" example (SDK 15.2) and try to apply changes to my application which was based on "Serial/" example. Regarding below code:

int main(void)
{
	board_system_init();
	modem_rst();

//	ret_code_t ret_code = nrf_pwr_mgmt_init();
//	APP_ERROR_CHECK(ret_code);

	ret_code_t mainErrCode = nrf_serial_write(&serial_uart, "\r\nSensor ready.\r\n", strlen("\r\nSensor ready.\r\n"), NULL, NRF_SERIAL_MAX_TIMEOUT);
	APP_ERROR_CHECK(mainErrCode);

	application_timers_start();

	while (true)
	{
	   	app_sched_execute();
//	   	nrf_pwr_mgmt_run();
	}
}

When nrf_pwr_mgmt_init(); and nrf_pwr_mgmt_run(); are off application works properly - I men when low power mode is disabled then logs from nRF board looks like below:

[14:56:27:301] Changing time interval to 3s␍␊
[14:56:30:280] ␍␊
[14:56:30:280] AT+CSQ␍␊
[14:56:30:317] ␍␊
[14:56:30:317] no range...␍␊
[14:56:33:280] ␍␊
[14:56:33:280] AT+CSQ␍␊
[14:56:33:333] ␍␊
[14:56:33:333] Range OK - Changing time interval to 20s␍␊

etc...

[14:56:27:249] REBOOT_CAUSE_SECURITY_RESET_UNKNOWN␍␊
[14:56:27:270] Neul ␍␊
[14:56:27:270] OK␍␊
[14:56:30:301] ␍␊
[14:56:30:301] +CSQ:99,99␍␊
[14:56:30:301] ␍␊
[14:56:30:301] OK␍␊
[14:56:33:302] ␍␊
[14:56:33:302] +CSQ:23,99␍␊
[14:56:33:302] ␍␊
[14:56:33:302] OK␍␊

etc...

But when I turn on low power mode I mean - when I uncomment part responsible for pwr mgmt: nrf_pwr_mgmt_init(); and nrf_pwr_mgmt_run(); 

Logs from board UART and modem looks like below:

BOARD:

[14:57:59:287] ␍␊
[14:57:59:287] Changing time interval to 3s␍␊

(and he is never wake up)

MODEM

[14:57:59:235] REBOOT_CAUSE_SECURITY_RESET_UNKNOWN␍␊
[14:57:59:256] Neul ␍␊
[14:57:59:256] OK␍␊

need(modem works OK)

If you need more info about the code pleas fell free to write.

BR's

Frank.

  • Hi,

    First of all you should check that you don't have an assert of some sort, and thereby may be hanging in the fault handler. I assume you have verified that the application_timers_start() are running at the periodic interval you have specified. In your infinite while(true) -loop you may consider adding some if() around the nrf_pwr_mgmt_run() to ensure that the app_sched_execute() have handled the tasks and that there is no pending serial transfer or log waiting before going to sleep. It's not really possible to go to low power while UART is enabled, so you will need to periodically enable and disable the UART if you want true low power, this can be done from an application timer and/or from an external GPIO if the peer want to send data at some time.

    Best regards,
    Kenneth

  • Hi Kenneth sorry for my delay, regarding yours ideas:


    I assume you have verified that the application_timers_start() are running at the periodic interval you have specified.

    Yes, without "sleep mode" application timers_start() are working properly -function is called
    one time before while(1) loop.

    In your infinite while(true) -loop you may consider adding some if() around the nrf_pwr_mgmt_run() to ensure that the app_sched_execute() have handled the tasks and that there is no pending serial transfer or log waiting before going to sleep.

    I add sentence

    if (NRF_LOG_PROCESS() == false)

    {

        nrf_pwr_mgmt_run();

    }

    after app_sched_execute(); in while() loop and effect was the same.

    It's not really possible to go to low power while UART is enabled, so you will need to  periodically enable and disable the UART if you want true low power, this can be done from an application timer and/or from an external GPIO if the peer want to send data at some time.

    Sure, thank you for info good to know. Is there any function, for example, nrf_serial_disable/halt or similar? Or you had on mind functions nrf_serial_uninit and nrf_serial_init?

    Unfortunately I have no idea why there is such effect that timer cannot wake up MCU - if you have any ideas please let me know. Best regards.

  • Frank_Knarf said:
    Yes, without "sleep mode" application timers_start() are working properly -function is called
    one time before while(1) loop.

    I am honestly not sure what may be the problem here. I suggest you try to take a look again at the BLE examples that use application timers with power management and try to figure out why it doesn't work in your case. Possible simplify your code or run the SDK examples as-is on your hardware first to make sure it works as intended. I suspect there may be something fundamental we are overlooking. 

    Frank_Knarf said:
    Or you had on mind functions nrf_serial_uninit and nrf_serial_init?

    I have not measured the timing to run _unint() or _init(), but provided there is no specific wait loops in there, that should work well.

    Best regards,
    Kenneth

Related