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

Disabling of UART Causing 8 mA increase in power draw

Hi. I  am implementing a low power operation in my firmware, but the UART de-initialization is causing me odd issues. In order to intialize, I call the function UART_Initialize() (placed below), and to de-initialize I call UART_DeInitialize() (also below). 

In doing this step of deinit, I add 8 mA current consumption. That obviously isnt right, but is there something dumb I am missing? I think I am following the correct process, but am open to any thoughts. 

To add, the function calls in the init and de-init below are unchanged from the SDK provided by Nordic.

Thank you!

uint32_t UART_Initialize(void)
{
    app_uart_comm_params_t const comm_params =
    {
        .rx_pin_no    = SMILERX_PIN_NUMBER,
        .tx_pin_no    = SMILETX_PIN_NUMBER,
        .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
        .use_parity   = false,
        .baud_rate    = NRF_UART_BAUDRATE_115200
    };

    uint32_t rtncode_uart = 0;
    APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_event_handle, APP_IRQ_PRIORITY_LOWEST, rtncode_uart);
    return rtncode_uart;
}

void UART_DeInitialize(void)
{
    nrfx_uarte_rx_abort();
    nrfx_uarte_tx_abort();
    app_uart_close();

    //https://devzone.nordicsemi.com/f/nordic-q-a/35510/uart-deinit-does-not-reduce-power-consumption-and-it-too-big-600ua
    //https://devzone.nordicsemi.com/f/nordic-q-a/26030/how-to-reach-nrf52840-uarte-current-supply-specification/102605#102605
    
    *(volatile uint32_t *)0x40002FFC = 0;
    *(volatile uint32_t *)0x40002FFC;
    *(volatile uint32_t *)0x40002FFC = 1;   
}

  • If the current jumps up to 8mA, it's probably because you get an assert (CPU running in a loop). app_uart_close() returns a value. Check if it is successful or not.

    nrfx_uarte_rx/tx_abort() should have the UART instance as an argument (is it really compiling without the argument?). https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.0/group__nrfx__uarte.html?cp=7_1_6_8_0_42_0_18#gada8aacc9576ce76945cda19f9525b187

    The 0x40002FFC register workaround is not necessary if the rx and tx abort is handled correctly. The old driver version did not handle it correctly (hence the workaround in the post you were linking to), but this was fixed a while ago. So use the newest nrfx drivers and you should be good. No need for the workaround. Btw, which SDK version are you using?

  • Thank you for your reply. A few follow-up questions (in order of your responses):

    If the CPU was running in a loop, my other code would not be running, correct? I can tell my code executes fine, due to the fact that it re-initializes all peripherals on the correct trigger post de-init. 

    The code was compiling fine, but it had a warning that the call was explicit (which I missed...stupid miss on my part), so the compiler just skipped the function. I have removed those, unless it is still valuable? I was unsure if it was needed. It seems like that should be covered in app_uart_close()?

    app_uart_close just returns success, looking at the function. The de-init function in it (nrf_drv_uart_uninit), is a void return function. Are you expecting a different de-init function? Digging further down, it seems none of the functions in deinitialize in the SDK will check return calls, so that may be the issue. Shouldn't these checks be implemented, i.e. should I modify the SDK to implement these checks?

    Finally, that is good to know on that workaround. My SDK version is 16.0.0. Does that contain the fix?

    Thank you again.

  • Thanks for the explanation. You are right that if the code continues to run, it is not asserting, and the UART should have been closed correctly.

    Sorry I wasn't aware that the UART de-init function just returns success. Anyways, as long as TX and RX are stopped properly the peripheral can just be disabled, and I can't really see anything that can go wrong.

    Could it be some issues with the pin configuration? If some of the pins are left as output and driving something externally? Just as a quick check you can try to set the relevant pins to disconnected input:

    NRF_GPIO->PIN_CNF[n] = 2;

    SDK 16 does contain the fix.

  • After a little digging, the solution ended up being something obvious. The UART was still flushing data on deinitialization, which for some reason meant the power went up when i tried to deinit. I added a function to verify the UART has flushed all data before the deinit, and the code was good to go. De-initing the uart dropped the power draw ~1.5 mA

Related