Zephyr UART Asynchronous API continuous data receiving

Hi all, 

I'm having problems receiving data from UART using Zephyr Asynchronous API. I've read documentation from UART — Zephyr Project Documentation and I think I understand how UART API new buffer requests work, to have always a seamless data receiving.

I'm providing 40 bytes length buffers. When sending from 1 to 80 bytes, all works as expected, but when sending more than 80 bytes at once, some data is lost.

I'm using nRF Connect SDK v1.9.1 with Zephyr v2.7.99. Arduino Nicla Sense Me board (Custom board as it is not supported yet in Zephyr v2.7.99).

This is the Asynchronous API callback:

static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
    ARG_UNUSED(dev);

    struct uart_data_t *buf;
    static struct uart_data_t *req_buf;

    switch (evt->type) {
    case UART_TX_DONE:
        break;

    case UART_RX_RDY:
        buf = CONTAINER_OF(evt->data.rx.buf, struct uart_data_t, data);
        buf->len = evt->data.rx.len;
        LOG_DBG("Rx %d bytes from id %d", buf->len, buf->uid);

        k_fifo_put(&fifo_uart_rx, buf);

        if (buf->len < UART_BUF_SIZE) {
            LOG_DBG("%s", "Manually disabling UART");      
            uart_rx_disable(uart);
        }

        break;

    case UART_RX_DISABLED:
        buf = k_malloc(sizeof(*buf));
        buf->uid = uid++;
        if (!buf) LOG_ERR("%s", "Not able to allocate buffer");
        LOG_DBG("RX_DISABLED. malloc %p, id %d", buf, buf->uid);
        uart_rx_enable(uart, buf->data, sizeof(buf->data), UART_WAIT_FOR_RX_US);

        break;

    case UART_RX_BUF_REQUEST:
        req_buf = k_malloc(sizeof(*req_buf));
        req_buf->uid = uid++;
        if (!req_buf) LOG_ERR("%s", "Not able to allocate buffer");
        LOG_DBG("BUF_REQUEST. malloc %p, id %d", req_buf, req_buf->uid);
        uart_rx_buf_rsp(uart, req_buf->data, sizeof(req_buf->data));
       
        break;

    case UART_RX_BUF_RELEASED:  
        break;

    case UART_TX_ABORTED:
        break;

    default:
        break;
    }
}

Executing the program and sending, for example, 150 bytes at once, gives the following traces:

*** Booting Zephyr OS build v2.7.99-ncs1-1 ***
D: FIRST ENABLE. malloc 0x20001680, id 0
D: BUF_REQUEST. malloc 0x200016b8, id 1
D: Rx 40 bytes from id 0
D: BUF_REQUEST. malloc 0x200016f0, id 2
D: Rx 40 bytes from id 1
D: RX_DISABLED. malloc 0x20001728, id 3
D: Rx 1 bytes from id 3
D: Manually disabling UART
D: BUF_REQUEST. malloc 0x20001760, id 4
D: RX_DISABLED. malloc 0x20001798, id 5
D: BUF_REQUEST. malloc 0x200017d0, id 6

Why automatically goes to UART_RX_DISABLED event after receiving first 80 bytes? If I send the same data in packets of 80 bytes with a delay between them, all data is received and no UART_RX_DISABLED is reached until I manually call uart_rx_disable(uart);

Is there any way to continuous receive any number of bytes concatenating any number of necessary buffers?

If I increase the size of the buffer to 120 bytes and send 370 bytes at once, a different behaviour (also not as expected) is observed:

*** Booting Zephyr OS build v2.7.99-ncs1-1 ***
D: FIRST ENABLE. malloc 0x20001680, id 0
D: BUF_REQUEST. malloc 0x20001708, id 1
D: Rx 120 bytes from id 0
D: BUF_REQUEST. malloc 0x20001790, id 2
D: Rx 120 bytes from id 1
D: BUF_REQUEST. malloc 0x20001818, id 3
D: Rx 120 bytes from id 2
D: BUF_REQUEST. malloc 0x200018a0, id 4

Only 360 bytes are notified to be received. Then I send just 1 byte and receive also the missing 10 bytes:

D: Rx 1 bytes from id 3
D: Manually disabling UART
D: Rx 10 bytes from id 3
D: Manually disabling UART
D: RX_DISABLED. malloc 0x20001928, id 5
D: BUF_REQUEST. malloc 0x200019b0, id 6

Another strange thing is when I change buffer size to 256 or 512 bytes, nothing works. No data is received. But with buffer sizes of 255, 257, 511 or 513 it works (Not as I expect, but works) It's very strange that changing buffer size the behaviour changes.

Please note that this is only an example and I'm not caring about freeing the allocated memory

Thanks in advance!

Pedro.

Parents Reply Children
No Data
Related