nRF_LOG UART draws ~300uA

Hello All,

I'm trying to get my application based on a nRF52832 to use as less power as possible and I've noticed that when the nRF_LOG UART is enabled it draws around 300 micro amps in SYSTEM ON with sd_app_evt_wait(). When I disable the nRF_LOG UART the current consumption is reduced to 14 micro Amps. I've already cut the traces between the UART and the J-link programmer on my BMD-300 Evalboard to determine if the pins where causing the additional current consumption, but that didn't help. It seems it's the UART peripheral that's drawing 300uA continuously.

Is it possible to disable the nRF_LOG's UART while the system is waiting for an event and only enable the UART when nRF_LOG_INFO has bytes to transmit?

Of course once development is complete I'll disable the UART output, but it would be great if I could get my application to the lowest power consumption while in sd_app_evt_wait().

Parents
  • The UART it self does not draw 300uA while it's not in TX/RX mode. So, this seems to be an issue with how the log module works together with the nrf_drv_uart driver.

    I noticed that the TASKS_STOPTX task is never called after the logging module is finished transmitting the buffer. I tried adding the following code to the uart_event_handler() in nrf_log_backend_serial.c, and the current was reduced to normal idle current:

    if (p_event->type == NRF_DRV_UART_EVT_TX_DONE)
    {
        NRF_UART0->TASKS_STOPTX = 1;
    }
    

    I have not tested this thoroughly, but it seems to work, so you can try it as well. I will report the issue internally so it will be fixed in future SDK releases. I tried this on SDK 13.

Reply
  • The UART it self does not draw 300uA while it's not in TX/RX mode. So, this seems to be an issue with how the log module works together with the nrf_drv_uart driver.

    I noticed that the TASKS_STOPTX task is never called after the logging module is finished transmitting the buffer. I tried adding the following code to the uart_event_handler() in nrf_log_backend_serial.c, and the current was reduced to normal idle current:

    if (p_event->type == NRF_DRV_UART_EVT_TX_DONE)
    {
        NRF_UART0->TASKS_STOPTX = 1;
    }
    

    I have not tested this thoroughly, but it seems to work, so you can try it as well. I will report the issue internally so it will be fixed in future SDK releases. I tried this on SDK 13.

Children
  • Thank you for your reply Stian. However this fix isn't working for me with SDK13.1.0. I've tried with both NRF_UART0->TASKS_STOPTX and the m_uart variable in the uart_event_handler within nrf_log_backend_serial.c as shown below:

     #if (NRF_LOG_BACKEND_SERIAL_USES_UART)
    static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
    {
        // Dummy handler since is_busy feature is used for determining readiness.
        if (p_event->type == NRF_DRV_UART_EVT_RX_DONE)
        {
            m_rx_done = true;
        }
    		
    		if (p_event->type == NRF_DRV_UART_EVT_TX_DONE)
    		{
    			//NRF_UART0->TASKS_STOPTX = 1;
    			//m_uart.reg.p_uart->TASKS_STOPTX = 1;		
    		}
    }
    #endif //NRF_LOG_BACKEND_SERIAL_USES_UART
    

    While debugging the event is called and the TASK_STOPTX is executed, but power consumption remains ~300uA. When I disable the NRF_LOG_BACKEND_SERIAL_USES_UART, the power consumption drop to a few uA.

    My while loop is as following:

        while (true)
    {	
    				/* Handle the Application statemachine each time the nRF52832 wakes-up. */
    				ApplicationStatemachine();
    			
    				// When the NRF LOG has been processed, go to a low power mode to conserve energy. The nRF will wake up on interrupt of anything; RTC, timers, SPI transfers, etc.
    				if (NRF_LOG_PROCESS() == false)
        {
          power_manage();
        }		
    }
    
Related