This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

UARTE enable, then disable

My project uses nRF52832 and I'm at the point of the project where I'm trying to minimize power consumption.

To assist in this, I created a very small main() that goes through all my peripherals/subsystems and turns them on, then off in one second intervals.    Using PowerProfiler II, I can then watch the power consumption and make sure that when I'm turning things off, I get back to the level where I was before the peripheral/subsystem was turned on.

I added each peripheral, one at a time, turning each on, then waiting 1 second, then turning it back off.   I also "beep" a buzzer, causing a "spike" in the power plot so it is easier to see where things are happening.   At the end of the "run" a call to nrf_pwr_mgmt_run(); drops to power to the idle level.

Things work well until I get to the UART.   I'm using nrf_libuarte_async_init() to turn the UART on, then enable Rx to get things going.    This is followed by a call to nrf_libuarte_async_uninit() to supposedly turn the UART back off. The power level drops a bit, but not nearly back down to the level it had been.   Something within the driver/lib must continue to run (besides the peripheral power still being on), as the nrf_pwr_mgmt_run() doesn't seem to do anything.

I saw a posting that suggest some low level calls to turn the actual UART off, but these don't seem to do anything to the power profile.

Can you suggest the proper sequence to get the UART back off?

Thanks!

Here is a power profile plot without the UART.  

You can see the "spikes" that indicate where other peripherals have been turned on or off.   The final step down is where the nrf_pwr_mgmt_run() occurs.

Here is a power profile plot with the UART:

You can see a couple of additional spikes for the UART.   The large step up is where the UART is turned on.  The small step down is where the UART is turned off.    The expectation is that the power level should go back to where it was before turning on, then fall lower when the nrf_pwr_mgmt_run() is called.

Here is the code for initialization and turnoff of the UART.

 void
uart_init(void) {
  ret_code_t err_code;

  // Set the configuration items
  nrf_libuarte_async_config_t nrf_libuarte_async_config = {
            .tx_pin     = USB_UART_RXD_PIN,
            .rx_pin     = USB_UART_TXD_PIN,
            .baudrate   = NRF_UARTE_BAUDRATE_9600,
            .parity     = NRF_UARTE_PARITY_EXCLUDED,
            .hwfc       = NRF_UARTE_HWFC_DISABLED,
            .timeout_us = 100,
            .int_prio   = APP_IRQ_PRIORITY_LOW
  };
  // Initialize the UART/library
  err_code = nrf_libuarte_async_init(&UART0,
                                     &nrf_libuarte_async_config,
                                     uart_event_handler, (void *)&UART0);
  APP_ERROR_CHECK(err_code);
  // Enable the UART receiver
//  nrf_libuarte_async_enable(&UART0);
}

 void
un_init_uart(void) {
  nrf_libuarte_async_uninit(&UART0);
  // From article    https://jimmywongiot.com/2021/05/23/advanced-uart-driver-libuarte-on-nordic-nrf5-sdk/
  *(volatile uint32_t *)0x40002000 = 0;
  *(volatile uint32_t *)0x40002000;
  *(volatile uint32_t *)0x40002000 = 1;
}

Note that for the last trial run, I commented out the  nrf_libuarte_async_enable(&UART0); call, thinking that perhaps it might give a hint of what might be causing the problem.

Here is the section of the "main" code where the UART calls are made...   

...
disableAccel();
#if 1
buzz(30);
nrf_delay_ms(1000);
uart_init();
buzz(30);
nrf_delay_ms(1000);
un_init_uart();
#endif
buzz(30);
...

Thanks again...

  • Hi

    What SDK version are you using specifically? It looks like an nRF5 SDK project, but please confirm that as well as which version exactly you're using.

    libuarte_async was designed to have RX always on, which is likely the main reason for this high current consumption. It's primary goal is to be able to reliably receive data even without flow control which is achieved by not stopping RX (ENDRX->STARTRX short). You can check out the latest edit by Sigurd in this thread, where he experimented with stopping the RX properly, and I think you should be able to achieve the lower current consumption by implementing this. 

    Is there a specific reason you're using libuarte and not the regular UARTE example for your application?

    Best regards,

    Simon

  • Hi Simon,

    Thanks!

    Yes, this is an nRF5 SDK project.  I'm using nRF_SDK_17.0.2_d674dde

    I'm using the UART for a test interface, and using the libuarte was convenient.   Just wanted to be able to completely power it down when not in test mode...

    Thanks again!

  • Let me know if you're tried the suggestion by Sigurd in the thread I linked to, and whether you got it up and running or not.

    Best regards,

    Simon

  • Hi Simon,

    I'm too far along in the project to replace libuarte with the simple UARTE  (we are about to go into production).    It looks like I can't use the code in the recommended link since it is not compatible with libuarte.   

    For now, when we put our device in test mode, libuarte is enabled, and when test mode exits, the device is reset, thereby disabling libuarte and we return back to the expected power level. 

    In the next version, I'll replace libuarte with a simple UARTE.

    Thanks!

  • Sorry if I misunderstood, but are you satisfied with the workaround you mention here? It sounds like a solid option to me, so I don't have any input on that. Let me know if we can close this case or if you have any follow up questions.

    Best regards,

    Simon

Related