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

Turn off UART on nrf52832

I noticed that having the UART enabled on my application in a NRF52 (SD132, SDK 11.0.0) takes a lot of current consumption. If I completely disable any UART support on my application the current consumption drops dramatically. I can't do that, but considering my device will be 99% of the time idle, I need to disabled the UART before I put the processor to sleep.

I am using FreeRTOS so what I did is I enabled the ApplicationIdleHook and did as follows:

/* FreeRTOS application idle hook */
void vApplicationIdleHook(void) {   
    // Disable UART transmission and reception
    bool uart_disabled = false;
    if (!nrf_drv_uart_tx_in_progress()) {
        NRF_UART0->TASKS_SUSPEND = 1;
        //NRF_UART0->ENABLE = 0; 
        uart_disabled = true;
    }

    __WFI();

    if (uart_disabled) {
        //NRF_UART0->ENABLE = 1;
        NRF_UART0->TASKS_STARTTX = 1;
        NRF_UART0->TASKS_STARTRX = 1;
   }    
}

That theoretically should suspend the UART but unfortunately it increases current consumption compared to simply doing __WFI() and leaving the UART as it is. Notice that if I enable the lines where I do NRF_UART0->ENABLE = 0 and NRF_UART0->ENABLE = 1 the UART simply stops working.

I wonder that is the right way to disable the UART when you go to sleep.

Parents
  • You are mixing up using UART driver and accessing registers directly. This will cause the unpredictable behavior you are seeing now. I recommend you to uninit UART and init again using the driver. Since you said that it will 99% in idle the overhead for uninit and init everytime it wakes up is negligible.

    /* FreeRTOS application idle hook */
    void vApplicationIdleHook(void) {   
        // Disable UART transmission and reception
        bool uart_disabled = false;
        if (!nrf_drv_uart_tx_in_progress()) {
            nrf_drv_uart_uninit(uart_instance);
            uart_disabled = true;
        }
    
        __WFI();
    
        if (uart_disabled) {
            nrf_drv_uart_init(xxx);
       }    
    }
    

    I think the reason that writing directly to ENABLE not working is because the pins are still configured to be connected to UART . Anyways, let the driver take care of this.

  • Hello Aryan, now I enable and disable the UART every single time I need to write something in it so I only do the __WFI() on the idle task. Still, I see the same behaviour. We're talking of about 700uA to 170uA when I completely disable any UART. Though I do not discard a mistake in the code, it looks like when the UART is disabled some hardware is still draining current. I'll try to make a simpler code sample to reproduce that. Also, the cpu is waken every 500ms by and also by the BLE hardware which advertises.

Reply
  • Hello Aryan, now I enable and disable the UART every single time I need to write something in it so I only do the __WFI() on the idle task. Still, I see the same behaviour. We're talking of about 700uA to 170uA when I completely disable any UART. Though I do not discard a mistake in the code, it looks like when the UART is disabled some hardware is still draining current. I'll try to make a simpler code sample to reproduce that. Also, the cpu is waken every 500ms by and also by the BLE hardware which advertises.

Children
No Data
Related