UART APP_UART_COMMUNICATION_ERROR

Dear Sirs!

I used SDK 12.2. Product was developed some years ago and now I am working for upgrade. One of new features is UART. I faced very strange problem.

I send 14 bytes from PC via FTDI UART 3.3V cable to Nordic and Nordic send back different 14 bytes to PC.

This process repeats each 200 ms

Baud rate 115200 no flow control, no parity

#define UART_RX_PIN_NUMBER 3 //UART Rx
#define UART_TX_PIN_NUMBER 2 //UART Tx
#define UART_CTS_PIN_NUMBER 0xFFFFFFFF //Not connected
#define UART_RTS_PIN_NUMBER 0xFFFFFFFF //Not connected
#define UART_HWFC false


static app_uart_comm_params_t comm_params =
{
UART_RX_PIN_NUMBER,
UART_TX_PIN_NUMBER,
UART_RTS_PIN_NUMBER,
UART_CTS_PIN_NUMBER,
APP_UART_FLOW_CONTROL_DISABLED, //Flow control disabled
false, //No parity
UART_BAUDRATE_BAUDRATE_Baud115200
};

buffers.rx_buf = rx_buf;
buffers.rx_buf_size = 64;
buffers.tx_buf = tx_buf;
buffers.tx_buf_size = 64;

err_code = app_uart_init(&comm_params, &buffers, uart_event_handle, APP_IRQ_PRIORITY_HIGHEST);

despite I use EASY_DMA

#ifndef UART_EASY_DMA_SUPPORT
#define UART_EASY_DMA_SUPPORT 1
#endif

// <q> UART_LEGACY_SUPPORT - Driver supporting Legacy mode

#ifndef UART_LEGACY_SUPPORT
#define UART_LEGACY_SUPPORT 0
#endif

I get sometimes event APP_UART_COMMUNICATION_ERROR error_communication  = 1

It happens randomly. May happen.  immediately or after 2 bytes received or after 6 bytes received

As I understood this value is the same as in register ERRORSRC. Is it correct?

How can I prevent this situation? I put interrupt to highest priority, use easy dma and fifo and despite all this it happens.

What''s wrong? Please help

Best regards

Michael

Parents
  • In the other thread you asked, 

    Is it really Overrun error
    A start bit is received while the previous data still lies in RXD?

    Does it mean that EASY DMA does not work, and interrupt is too slow to read data to FIFO?

    The EasyDMA does work correctly and has nothing to do with this error. The overrun error is caused because the peer is transmitting data even after the RXD buffer is full in your nRF device and since you have disabled flowcontrol, there is no way to communicate this with the peer.

    This issue is happening because you have disabled flow control and using high baudrate. Do not focus your energy assuming that this is a hardware issue. Just reconfigure your firmware to enable flow control and/or reduce the baudrate and you will not see this error. The overrun error is working proper and this is how the UART works.

  • Please answer my question. I have FIFO 64 bytes. When byte arrive to RX register, is it correct, that DMA copy it to FIFO buffer immediately without processor? Or despite of easy DMA processor shall call interrupt routine?

  • The firmware FIFO you have is different than the hardware FIFO you have inside the UART

    PMichael said:
    is it correct, that DMA copy it to FIFO buffer immediately without processor?

    Yes, EasyDMA will copy from the internal buffer to the RAM buffer of given size for one transaction. After this one transaction the CPU gets an interrupt and need to process the received bytes in RAM that the easydma already transferred. Reconfigure the easydma RXD.PTR register and get ready for more data to be received. But if the interrupt handler or the callback inside the application that the interrupt service routine calls take too long time, then there is a risk of buffer overflow. That is the exact reason why you have flow control. 

    Do you understand the implications of what happens if you disable flow control on UART? 

  • Thank you.

    You wrote  "given size". Can I control this size? Or it is constant number of bytes?

    Is it a RAM buffer that I define in app_uart_buffers_t structure?

Reply Children
  • The RAM buffer can be of any variable size from 1-255 which can be configured in TXD.MAXCNT and RXD.MAXCNT register.

  • Thank you.

    As I wrote in first message I init UART

    buffers.rx_buf = rx_buf;
    buffers.rx_buf_size = 64;
    buffers.tx_buf = tx_buf;
    buffers.tx_buf_size = 64;

    err_code = app_uart_init(&comm_params, &buffers, uart_event_handle, APP_IRQ_PRIORITY_HIGHEST);

    Does it mean that RXD.MAXCNT register will be 64 or it is something different?

    Please elaborate.

  • No, those buffers are the size of the fifo we choose in app_fifo module.

    The MAXCNT is set when you use nrf_drv_uart_tx. The length argument in nrf_drv_uart_tx goes to the TXD.MAXCNT register. Same goes with nrf_drv_uart_rx and RXD.MAXCNT register.

  • I look at app_uart_init code and see only

    return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1);

    It means that RXD.MAXCNT will be 1.

    Is it correct?

    If yes, additional question:

    Assume that I use baud rate 115200 8 bit no parity (totally 10 bit). Does it mean that UART interrupt routine shall be evoked with delay less than about 85 us.

    And in case that baud rate is 57600 maximum delay shall be about 170us?

    Thank you

  • PMichael said:
    It means that RXD.MAXCNT will be 1.

    Yes, you are right. It is then using only one byte transfer.

    PMichael said:

    Assume that I use baud rate 115200 8 bit no parity (totally 10 bit). Does it mean that UART interrupt routine shall be evoked with delay less than about 85 us.

    And in case that baud rate is 57600 maximum delay shall be about 170us?

    The interrupt service routine can take an addition 12 cycles of HFCLK apart from the 85us to clock out/in the data at baud 115200. Since you are using nrfx_ driver->nrf_drv->app_fifo->app_uart->your application callback handler for uart events, then the latency increases. I do not know this latency by heart but you can measure it by toggling a gpio in the first line of the ISR to the first line in your uart callback handler.

    Please ask any new questions in a new thread, this thread is starting to become a bit messy with many questions that do not match the title of the thread anymore.

Related