Zephyr 2.4.0 with Async UART

Hi, 

   I am having the same problem as nRF9160 UART: Loosing data when RxData is split into 2 buffers (Async API) - Nordic Q&A - Nordic DevZone - Nordic DevZone (nordicsemi.com) and ASYNC uart and UART_RX_RDY timeout - Nordic Q&A - Nordic DevZone - Nordic DevZone (nordicsemi.com). I have tried the solution, namely modifying 

uart_nrfx_uarte.c

prj.config

However, I end up with this error

Ultimately, I would like this problem resolved. If I'm missing something obvious, please let me know. 

Parents
  • The solution that was proposed is very old and hence definitely not API compatible with the newer ncsv2.4.0.

    The pull request the other thread is showing seems to be merged. So I am confused that you are using ncsv2.4.0 and still have to patch the files with the PR changes? Shouldn't the changes be already in?

  • I modified DEVZONE Academy lesson 5 to echo back received data. I found that the echo shows data is getting missed. I am not sure how to resolve this issue. 

    It makes sense that data is being missed when the RECEIVE_BUFF_SIZE is less then the length of the data being sent. However, I notice missed data even when I increase the buffer size. 

    What is going on here? 

    3583.fund_less5_exer1_solution.zipI  

  • Hi Susheel, 

       I believe I have resolved the problem. I thought the problem was in the prj.config setting when compared with the devacademy lesson (lesson 5). However, I found (I think) that the problem lies with Zephyr. 

    The problem appears to be

    1. When the buffer fills up, the system has a problem. Data is lost. 

    2. Double buffering also doesn't resolve the problem, it merely pushes the problem into the future

    So the solution can benefit from double buffering, but is not resolved by it. Nor is it resolved with a  UART_RX_BUF_REQUEST or UART_RX_BUF_RELEASED event. The system uses a second buffer when the first one fills up. However, when it switches to the second buffer, it doesn't seem to let you setup a new secondary buffer. This is a problem, because when the secondary buffer fills up, then you loose data. 

    What did I try? 

    1. I tried setting up a new secondary buffer upon a "UART_RX_BUF_REQUEST" event 

    After all, this occurs when you have started receiving for a new buffer. It should be as simple as calling "uart_rx_buf_rsp(...)" to setup a new secondary buffer. However, this doesn't work. A problem is still encountered when the old secondary buffer is filled. 

    2. I tried forcing a reset of the UART buffers (within UART_RX_RDY)

    Every time data is received, a UART_RX_RDY event will at some point occur. So, after copying the data, disabled the UART RX side. Then, re-enable and setup your buffers again. In this case, if I start out with Primary Buffer as "Buffer A", and my Secondary Buffer as "Buffer B", I then make my new Primary Buffer "Buffer B", and my new Secondary Buffer "Buffer A"

    Buffer A should never fill up. Before it fills up, you have switched the buffers around. So your two buffers aren't providing overrun protection per say. Rather, they are providing an empty runway every time you receive data. 

        case UART_RX_RDY:
            tracking = 1;
            int i = 0;
            uint8_t temp = 0;
            uint8_t length = evt->data.rx.len;

            for(i = 0i<evt->data.rx.len; i++)
            {
                temp = evt->data.rx.buf[evt->data.rx.offset + i];
                tx_buf2[i= temp;
            }
            ret = uart_rx_disable(dev);
            ret = uart_tx(dev ,tx_buf2,length,SYS_FOREVER_MS);
            break;
        case UART_RX_DISABLED:
            tracking += 1;
            if (rx_buf_indicator == 0)
            {
                ret = uart_rx_enable(dev ,rx_buf1,sizeof(rx_buf1),RECEIVE_TIMEOUT);
                ret = uart_rx_buf_rsp(dev, rx_buf0, sizeof(rx_buf0));
                rx_buf_indicator = 1;
            }
            else
            {
                ret = uart_rx_enable(dev ,rx_buf0,sizeof(rx_buf0),RECEIVE_TIMEOUT);
                ret = uart_rx_buf_rsp(dev, rx_buf1, sizeof(rx_buf1));
                rx_buf_indicator = 0;
            }
            break;

    And I set the prj.config settings back to the defaults from lesson 5, and that doesn't seem to make a difference. 

    ## These prj.config settings work

    CONFIG_SERIAL=y
    CONFIG_UART_ASYNC_API=y

    ## These prj.config settings also works

    CONFIG_SERIAL=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_0_INTERRUPT_DRIVEN=n
    CONFIG_UART_LINE_CTRL=y
    CONFIG_UART_ASYNC_API=y
    CONFIG_UART_0_ASYNC=y
    CONFIG_UART_0_NRF_HW_ASYNC=y
    CONFIG_UART_0_NRF_HW_ASYNC_TIMER=1
    CONFIG_NRFX_UARTE0=y
    CONFIG_NRFX_TIMER1=y
    CONFIG_NRFX_PPI=y
    Please provide input
    1.The problem didn't appear to be with the prj.config file.
    2. The solution didn't appear to be in the DEVACADEMY example.
    3. I also have a mild worry about dropped data that could be caused by disabling the UART_RX stream.\
    4. I would also like to confirm why this is a problem or a better way to resolve this ASYNC UART problem...? 
  • Canadian_EE said:
    4. I would also like to confirm why this is a problem or a better way to resolve this ASYNC UART problem...? 

    Hi Canadian_EE,

    I missed to see the last questions. I do see any questions in point 1 and 2. 

    3. Every application is different in terms of dropped data. There should not be any dropped data at all if you are using a hardware flow control. Are you sure that you have set the hardware flow control for uart. (It is normally set in the uart_configure function). I do not see how the data is dropped or lost with hwfc unless the app is not handling the buffers correctly.

    4. Reading the source code in ncsv2.4.1, I see that data loss should not happen with hardware flow control enabled. And your workaround seems to be acting as if the hardware flow control is disabled in your setting and you are trying to handle double buffers just to give some extra buffer space for the incoming and outgoing data.

  • Hi Susheel, 

         UART with DMA should not drop data, particularly when the buffer rolls over. In my opinion, this isn't a hardware flow control or not flow control issue. Flow control might help, but the DMA with interrupts should properly handle the buffer filling up. The fact that the ASYNC UART DMA approach doesn't work properly indicates a problem or flaw with the Nordic Zephyr ASYNC UART. The DMA should alleviate the need for for flow control by providing a continuous receive capability. 

    Also, the prj.config settings do not appear to make a difference. Why is that? 

  • Canadian_EE said:
    In my opinion, this isn't a hardware flow control or not flow control issue. Flow control might help, but the DMA with interrupts should properly handle the buffer filling up.

    Well the easyDMA is not the only variable that effects the throughput of the application. The applicaiton normally have post processing latencies for every serial transaction which is more than making a new request. You need to analyze how much time is spend with every transaction of data received/sent in your application. If you are not processing the data at all (ignoring the incoming data) and only spending time in the application to reconfigure the DMA pointers, then I would understand your logic of flow control not needed with EasyDMA. You can do a simple test of lowering the baudrate on both sides and see if you see the same issue. If you do, then what I think about flow control and throughput even with Async UART is correct. If you do not see the same issue, then we can remove the flow control from our discussions.

  • Hi Susheel, 

       can you explain your comment again? I don't quite follow what you mean. 

Reply Children
No Data
Related