nRF5340 UART Interrupt mode send example

Hi all!
I'm currently working on the UART on the nRF5340 board. The SDK describes three options:
-polling API, -interrupt-driven API, -asynchronous API.
With Polling and Asynchronous - everything is clear and they do not suit me for various reasons.
Interrupt-driven doesn't have any APIs for starting (sending the first byte).
Searched everything.
Please share a link to an example.
Parents
  • Hi,

    So that we are on the same page: Can you send me the link to the documentation you refer to?

    The SDK describes three options:

    Regards,
    Sigurd Hellesvik

  • Hello Sigurd!
    
    I have already searched through mountains in search of information. Start here
    UART — Zephyr Project Documentation (nordicsemi.com)
    
    I used the "peripheral_uart" example from SDK 2.0.0 to start with, but it uses an asynchronous uart.
    I couldn't find an example with an interrupt driven API.


  • Hi Torbjørn

    Of course, transferring between internal devices via DMA is preferable, but specifically with UART this can cause problems.

    Let me explain with an example: if you need to receive a packet of 8 bytes, and set DMA to 8 bytes, then the impulse noise, "lowering" the RxD line for the time of the start bit, will ruin everything, and the false byte will be received first, then the 7th will be received byte of the packet, and the 8th byte will be lost.

    And when using STX / ETX, the length of the packets can vary greatly due to the replacement of codes, and programming the DMA length will be a problem.

    p.s. EazyDMA is a great idea!

    Best regards, Sergey.

  • Hi Sergey

    Thanks for explaining the issue in more detail. 

    The way we handle this issue using EasyDMA (and the issue of buffer overrun in general) is to make the DMA pointer double buffered. Once you have configured the first buffer through the RXD.PTR register (or by using a higher level driver to do the same), and started the RX reception, you can then proceed to write a second buffer to the RXD.PTR register. 

    As soon as the first buffer fills up the hardware peripheral will seamlessly switch to the second buffer, meaning you can continue receiving without any gap in the communication. 

    On completion of the first buffer you will get an interrupt from the peripheral, allowing you to set up the third buffer while the second buffer is being filled up. And so on. 

    Based on the UART baudrate used and the number and length of interrupts in your system you can scale the RX buffers to ensure that an overrun will never happen. 

    Best regards
    Torbjørn

  • Hi Torbjørn
    Of course, a double buffer is also a very good solution and of course I use it, but if the packets go one after the other, then two packets appear in one buffer, and often the packet is located simultaneously in two buffers, which is not very convenient.
    Best regards, Sergey.

  • Hi Sergey

    Whether or not you use DMA this is a result of the asynchronous nature of UART communication. 

    You need some kind of algorithm on the receiving side that goes through the incoming bytes one by one, and figures out what is the start and end of each packet, before the packet is sent to the application for processing. 

    The only difference is whether each RX callback could contain 1 or multiple bytes. In the case of DMA you might get multiple bytes at once, which means you need to loop through each one and run the packetization algorithm like mentioned above. 

    Best regards
    Torbjørn

  • Hi Torbjørn

    thanks for answers!

    
    

    Best regards, Sergey.

Reply Children
Related