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

About a procedure with UART as disable

Because of the power-saving support, I want to disable the UART before Call the sd_app_evt_wait().

I referred to two following sites to know the procedure of the case. 1.https://devzone.nordicsemi.com/question/5186/how-to-minimize-current-consumption-for-ble-application-on-nrf51822/?answer=5187#post-id-5187

2.https://devzone.nordicsemi.com/question/1119/handling-the-uart-when-sleeping/

However, there is for difference at the point that execute the following code when disable does UART in a procedure written as 1 to 2.


// Set TXD, RXD, CTS, RTS as high outputs
// Alternatively use NRF_GPIO->PIN_CNF to set pull resistors

NRF_GPIO->DIRSET = (1 << UART_TXD_GPIO) | (1 << UART_RXD_GPIO) | (1 << UART_RTS_GPIO) | (1 << UART_CTS_GPIO);

NRF_GPIO->OUTSET = (1 << UART_TXD_GPIO) | (1 << UART_RXD_GPIO) | (1 << UART_RTS_GPIO) | (1 << UART_CTS_GPIO);

As a result of having tried each procedure, I became able to reuse UART in 2 procedures, but UART did not become reusable in 1 procedure.

When disable does UART, is it right to perform in a procedure listed in 2?

  • Hi satokato,

    Are you using simple_uart code? In procedure 1) the code is changing the pin directions when disabling but not setting them back to their usable state when you have to re-use UART again. I do not think you need reset the GPIO direction as that will not change power consumption.

    The code in the procedure 2) simple_uart_putstring which starts UART when needed to transmit and stops when last byte is transmitted is perfect. simple_uart_put will make sure that the it waits until the byte is transmitted before stopping the the uart.

    But the given solutions were only for TX, That will keep RX ON all time. If you want to toggle RX also then you can do like below

    uint8_t simple_uart_get(void)
    {
           
        NRF_UART0->TASKS_STARTRX = 1;
    
        while (NRF_UART0->EVENTS_RXDRDY != 1)
        {
            // Wait for RXD data to be received
        }
    
        NRF_UART0->EVENTS_RXDRDY = 0;
    
        NRF_UART0->TASKS_STOPRX = 1;
        return (uint8_t)NRF_UART0->RXD;
    }
    

    Note that if you switch RX on as you need, then you need to know when the peer device will transmit else you this device might be sleeping with RX off when the other device sends byte and it will be lost.

  • Hi Aryan, Thank you for reply.

    Sorry.I'm using app_uart_fifo Code. When I use app_uart_fifo, are the procedures different?

  • Hi Satokato,

    Yes, it is lot different with app_uart_fifo. This module uses lower level driver nrf_drv_uart. The easiest is to do an unit when not need and init when you wakeup again. This adds little latency but your problem will be solved without hacking the library and driver

    while(your_condition)
    {
        err_code = app_uart_close();
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);
    
        APP_UART_FIFO_INIT( &comm_params,
                           UART_RX_BUF_SIZE,
                           UART_TX_BUF_SIZE,
                           uart_event_handle,
                           APP_IRQ_PRIORITY_LOW,
                           err_code);
        APP_ERROR_CHECK(err_code);
    }
    

    But remember one thing, because you are disabling UART before you go to sleep, you cannot use UART events to wakup your system, that wont work. Any other event to wake your system will work as usual.

  • Hi,Aryan, Thank you for advice.

    Unfortunately I do not use nrf_drv_uart in my project now. There is the following same function, can you use it in substitution for your advice?

    ・uint32_t app_uart_close(uint16_t app_uart_id);

    Or must I introduce nrf_drv_uart?

  • Hi Satokato,

    I am confused, you said you are using app_uart_fifo library and this one uses nrf_drv_uart driver. Did you implement your own app_uart_fifo without using the nrf_uart_driver?

Related