Device PowerManagement and NRF Uarte

Hi!

I want to integrate power management into our FW. Therefor I did enable it in the prj.conf:

CONFIG_PM_DEVICE=y
CONFIG_PM_DEVICE_RUNTIME=y

And added runtime enable and action run calls regarding this device during bootup phase:

error = pm_device_runtime_enable(dev);
....
error = pm_device_action_run(dev, PM_DEVICE_ACTION_RESUME);
....
error = uart_rx_enable(dev, buffer, UART_BUFFER_SIZE, UART_RECEIVE_TIMEOUT);
....

To test the pm of the UART, I created a timer which, when expired, switches between suspend and resume for this uart.


After BootUp, this timer is not yet started. So the uart was configured, pm runtime was enabled and the dev was resumed after runtime enable.
Therefor the device is active and I can send a message to it and receive an answer.

However, after the first message exchange, the timer (for pm tests) is activated. It does the switch between active->suspended->active and the UART stopped working.

Here the code which does the switch:

ret = pm_device_state_get(dev, &state);
if (ret == 0)
{
    if (state == PM_DEVICE_STATE_SUSPENDED)
    {
        ret = pm_device_action_run(dev, PM_DEVICE_ACTION_RESUME);
        LOG_INF("pm action run ret: %d, new state: %s", ret, pm_device_state_str_get(dev));
    }
    else if(suspend > 0)
    {
        ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND);
        LOG_INF("pm action run ret: %d, new state: %s", ret, pm_device_state_str_get(dev));
        suspend--;
    }
}

For testing, I added an counter "suspend" which is static set to 1 to suspend only once.

Any Idea, why the uart receives only Zero-Bytes after the second switch between active and suspended?
And I get some Overrun errors, but I think this is not the cause but impact of the problem, as the overrun errors start to appear after the first byte received:

[00:00:06.938,110] <inf> d_uart: pm action run ret: 0, new state: active
[00:00:09.444,946] <inf> d_uart: uart@8000: received 1 bytes from queue.
[00:00:09.444,976] <inf> m_isn_uart_if: 0x00
[00:00:11.706,573] <err> d_uart: uart@8000: RX Stopped! Reson(0x01): ERROR_OVERRUN
[00:00:11.706,634] <err> d_uart: uart@8000: RX Stopped! Reson(0x01): ERROR_OVERRUN
[00:00:11.706,726] <err> d_uart: uart@8000: RX Stopped! Reson(0x01): ERROR_OVERRUN
[00:00:11.706,817] <err> d_uart: uart@8000: RX Stopped! Reson(0x01): ERROR_OVERRUN
[00:00:11.706,878] <err> d_uart: uart@8000: RX Stopped! Reson(0x01): ERROR_OVERRUN
[00:00:11.706,970] <err> d_uart: uart@8000: RX Stopped! Reson(0x01): ERROR_OVERRUN
[00:00:11.707,092] <wrn> d_uart: uart@8000: Buffer released!
[00:00:11.707,122] <wrn> d_uart: uart@8000: Buffer released!
[00:00:11.707,122] <wrn> d_uart: uart@8000: Disabled!
[00:00:11.707,153] <wrn> d_uart: uart@8000: Buffer requested!

Cheers,
Thilo

Parents
  • Forgot the pinctrl dts:

    &pinctrl {
    	uart0_default: uart0_default {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, 19)>,
    				<NRF_PSEL(UART_RTS, 1, 3)>;
    		};
    		group2 {
    			psels = <NRF_PSEL(UART_RX, 0, 21)>,
    				<NRF_PSEL(UART_CTS, 1, 5)>;
    			bias-pull-up;
    		};
    	};
    
    	uart0_sleep: uart0_sleep {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, 19)>,
    				<NRF_PSEL(UART_RTS, 1, 3)>,
    				<NRF_PSEL(UART_RX, 0, 21)>,
    				<NRF_PSEL(UART_CTS, 1, 5)>;
    			low-power-enable;
    		};
    	};
    };

    And the usage of the pinctrl:

    &uart0 {
    	status = "okay";
    	current-speed = <115200>;
    	pinctrl-0 = <&uart0_default>;
    	pinctrl-1 = <&uart0_sleep>;
    	pinctrl-names = "default", "sleep";
    };
    

Reply
  • Forgot the pinctrl dts:

    &pinctrl {
    	uart0_default: uart0_default {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, 19)>,
    				<NRF_PSEL(UART_RTS, 1, 3)>;
    		};
    		group2 {
    			psels = <NRF_PSEL(UART_RX, 0, 21)>,
    				<NRF_PSEL(UART_CTS, 1, 5)>;
    			bias-pull-up;
    		};
    	};
    
    	uart0_sleep: uart0_sleep {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, 19)>,
    				<NRF_PSEL(UART_RTS, 1, 3)>,
    				<NRF_PSEL(UART_RX, 0, 21)>,
    				<NRF_PSEL(UART_CTS, 1, 5)>;
    			low-power-enable;
    		};
    	};
    };

    And the usage of the pinctrl:

    &uart0 {
    	status = "okay";
    	current-speed = <115200>;
    	pinctrl-0 = <&uart0_default>;
    	pinctrl-1 = <&uart0_sleep>;
    	pinctrl-names = "default", "sleep";
    };
    

Children
No Data
Related