UART RX missing bytes -event buffer length and offset mismatch-NRF Connect SDK

Hi, greetings all !!

I am developing an application based on ble_uart_peripheral example on nrf52dk_nrf52832 using NRF Connect SDK2.1. In my application, I have to receive bytes from an external client via UART. The problem is, at high baud rate, some of my bytes get missed. For example, while debugging, the evt->data.rx.offset shows 4 but evt->data.rx.len shows 2. So, when i try to read the buffer, based on offset value, I miss bytes. HW flow control is not an option for me since that would involve changes to my client as well. Is there anything else I can do to get this working ? I thought it might be an overrun case, but that was not the error cause.

Any ideas ?

Parents
  • Hi,

    Do you expect offset and len to always be the same? As described in uart_event_rx struct documentation: "The data represented by the event is stored in rx.buf[rx.offset] to rx.buf[rx.offset+rx.len]. That is, the length is relative to the offset." Is this how you read out data from the buffer in the event?

    Best regards,
    Jørgen

  • Hi Jorgen,

    maybe i am not making myself clear here. This is my code.

    case UART_RX_RDY:
    		LOG_DBG("UART_RX_RDY");
    		buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data);
    		buf->len += evt->data.rx.len;
    		if (disable_req) {
    			return;
    		}
    		uint8_t data_t = *(buf->data+evt->data.rx.offset);
    		packetDecode(data_t,eSrc_UART);
    
    		if ((evt->data.rx.buf[buf->len - 1] == '\n') ||
    		    (evt->data.rx.buf[buf->len - 1] == '\r')) {
    			disable_req = true;
    			uart_rx_disable(uart);
    		}
    		
    		break;

    This is part of the default uart_cb() that was part of the peripheral uart example. I am expecting that when each byte is received, I will get this interrupt and i will get that in data_t variable. Please correct me if my understanding is wrong or if there is a better implementation.
    I dont feel that the logic is wrong though. Since, when there is a 1s gap between each byte transmitted from my client, I get all the bytes with no hassle in the data_t variable.

    Please advise. Thanks for your time.

Reply
  • Hi Jorgen,

    maybe i am not making myself clear here. This is my code.

    case UART_RX_RDY:
    		LOG_DBG("UART_RX_RDY");
    		buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data);
    		buf->len += evt->data.rx.len;
    		if (disable_req) {
    			return;
    		}
    		uint8_t data_t = *(buf->data+evt->data.rx.offset);
    		packetDecode(data_t,eSrc_UART);
    
    		if ((evt->data.rx.buf[buf->len - 1] == '\n') ||
    		    (evt->data.rx.buf[buf->len - 1] == '\r')) {
    			disable_req = true;
    			uart_rx_disable(uart);
    		}
    		
    		break;

    This is part of the default uart_cb() that was part of the peripheral uart example. I am expecting that when each byte is received, I will get this interrupt and i will get that in data_t variable. Please correct me if my understanding is wrong or if there is a better implementation.
    I dont feel that the logic is wrong though. Since, when there is a 1s gap between each byte transmitted from my client, I get all the bytes with no hassle in the data_t variable.

    Please advise. Thanks for your time.

Children
No Data
Related