This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
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

sending UART

Hi. I'm using PCA10028, SDK10.0.0, S130.

I want to go to nrf_drv_uart_uninit(); right after sending data. in order to save current consumption.

So I made source code as below.

uart_start_sending=1;
for(int i=0;i<datalen;i++) app_uart_put(ptrData[i]);

......

void uart_event_handle(app_uart_evt_t * p_event) {

......

    case APP_UART_TX_EMPTY:
		if(uart_start_sending)
		{
			uart_start_sending=0;
             		nrf_drv_uart_uninit();

		}
        break;

......

}

But I can't send last 1 byte. For example, if i send 20 bytes, i can send 19bytes but not 20th byte.

I think, UART goes to disable mode(nrf_drv_uart_uninit) before sending last byte.

How can I send all bytes then go to sleep mode? I need your help.

Parents
  • Seems like this is a bug in the SDK. If you look at uart_event_handler() in app_uart_fifo.c, you can see that when it gets the NRF_DRV_UART_EVT_TX_DONE event, it will transfer one byte from the FIFO and send it using nrf_drv_uart_tx(). If this is the last byte in the FIFO then the FIFO will be empty. Then on the next line it checks if the FIFO is empty and then issue the APP_UART_TX_EMPTY event, before the last byte has been sent.

    IMO the two IF statements should have switched places like this:

    else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE)
    {
        if (FIFO_LENGTH(m_tx_fifo) == 0)
        {
            // Last byte from FIFO transmitted, notify the application.
            // Notify that new data is available if this was first byte put in the buffer.
            app_uart_event.evt_type = APP_UART_TX_EMPTY;
            m_event_handler(&app_uart_event);
        }
        // Get next byte from FIFO.
        if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS)
        {
            (void)nrf_drv_uart_tx(tx_buffer,1);
        }
    }
    

    I tried with the above code and it transmitted all bytes. I will report this internally as a bug.

Reply
  • Seems like this is a bug in the SDK. If you look at uart_event_handler() in app_uart_fifo.c, you can see that when it gets the NRF_DRV_UART_EVT_TX_DONE event, it will transfer one byte from the FIFO and send it using nrf_drv_uart_tx(). If this is the last byte in the FIFO then the FIFO will be empty. Then on the next line it checks if the FIFO is empty and then issue the APP_UART_TX_EMPTY event, before the last byte has been sent.

    IMO the two IF statements should have switched places like this:

    else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE)
    {
        if (FIFO_LENGTH(m_tx_fifo) == 0)
        {
            // Last byte from FIFO transmitted, notify the application.
            // Notify that new data is available if this was first byte put in the buffer.
            app_uart_event.evt_type = APP_UART_TX_EMPTY;
            m_event_handler(&app_uart_event);
        }
        // Get next byte from FIFO.
        if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS)
        {
            (void)nrf_drv_uart_tx(tx_buffer,1);
        }
    }
    

    I tried with the above code and it transmitted all bytes. I will report this internally as a bug.

Children
Related