This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Calling nrvdrv_uart_rx_abort() results in error event, not read ready event

I'm calling nrf_drv_uart_rx_abort() in order to read partially captured input from UART in my event handler.

However, instead of receiving a NRF_DRV_UART_EVT_RX_DONE event (as per documentation) I'm getting a NRF_DRV_UART_EVT_ERROR.

I can see that both ERROR and RXTO events are set (and indeed, the data does sometimes look corrupt when looking in the rx buffer).

Why is this happening? I don't get any errors when I'm not calling nrf_drv_uart_rx_abort() - but I have to wait until my buffer is full, which doesn't work for my application (the data size is not known in advance).

I'm using UARTE, non-blocking, EASY DMA. My buffer size is 8 bytes (but I've tried various sizes - the problem exists at all sizes above 1). The problem exists when using both single and double buffering, and I've tried using higher prio interrupts for the UART event handler.

Parents
  • I've not managed to resolve this problem... but I have managed to avoid it by refactoring my code to use the libuarte library. It was a pretty simple change - mostly just mapping the structures and methods like-for-like: only tricky part was understanding the timers (softdevice enabled).

    So... in my view there's clearly still a problem in the UARTE driver - either the code or the docs. But I must say the libuarte library is doing everything I need it to and more (I've managed to now push it to 1M baud with no issue, which is great).

  • Thanks for updating the case with your solution! Libuarte should be a good choice for this. With regards to the error event, did you have HW flow control enabled to stop reception when you issued the stop task? If not it may be easy to overflow the receive buffer and thus get a receive error.

    Excerpt from PS (link)

    ..With flow control disabled, the UARTE will function in the same way as when the flow control is enabled except that the RTS line will not be used. This means that no signal will be generated when the UARTE has reached the point where it is only able to receive four more bytes in its internal RX FIFO. Data received when the internal RX FIFO is filled up, will be lost.

  • No, I don't use HWFC (these signals aren't connected between my CPUs)... but its an interesting theory. Does the abort rx task abort both the current and back buffer (if using double buffering)? That's not something I'd considered but in the context of your question it would make sense - and if it is the case that might be worth clarifying in the docs.

    I've only had a cursory look at the inner workings of the libuarte library, but it appears to not work in this way (issuing an abort task in order to receive partial data) and instead examines the amount received in the timer interrupt.

  • The STOPRX task stops reception even if it's double buffering is used. It's maybe something that could have been made more clear in the documentation.

    Stids said:
    I've only had a cursory look at the inner workings of the libuarte library, but it appears to not work in this way (issuing an abort task in order to receive partial data) and instead examines the amount received in the timer interrupt.

    Libuarte enables you to use large DMA buffers and still get data events for small transactions. It relies on the EVENTS_RXDRDY event in combination with timers to achieve this (RXDRDY is triggered for every received byte regardless of DMA buffer size). Please see the "Libuarte - advanced UARTE driver" for a more detailed description of how it works.

  • Thanks Vidar. Yes the use of RXRDY and timers clearly works extremely well and it's great you've offered up this library so we don't have to roll our own using this (pretty complicated!) approach :-)

Reply Children
No Data
Related