FX3 single byte UART receive with DMA

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
LeRi_4466366
Level 1
Level 1
First like given

I want to be able to receive single bytes over UART and prefer using DMA as it is working great for UART TX.

I followed the instructions in https://community.cypress.com/thread/27763?q=FX3%20single%20byte%20UART%20receive%20with%20DMA  and followed the suggestions of  gaalc_291501​ .

This involved setting up the UART ISR to be triggered when data is received via UART and incrementing a variable each time this happens.

When the dma callback gets triggered the counter is cleared.

In another thread I watch the counter and compare it to it's previous known value and sleep. If the counter is non-zero and is the same as before before sleeping it means we stopped receiving data and should call SetWrapUp to push the contents of the DMA buffer "early".

This sort of works but after a while (usually > 1000 bytes) a byte gets "stuck" in the buffer. I know it is received because the next byte sent will "dislodge" the byte (and two bytes are received).

My guess is this is caused by either a race condition involving the counter variable or the UART ISR does not reliably trigger when data is received.

So is it possible to read how many bytes are waiting in the UART RX DMA buffer?

Also if anyone has dealt with this before or has an idea of another solution I am all ears.

0 Likes
1 Solution

Hello,

According to my understanding you are talking about the DMA channel between UART producer socket and USB consumer socket. Please feel free to correct me if I'm wrong.

If this is the channel, then even if the PROD event does not occur, the buffer will be committed. This is because you can see that in USBUARTAppThread_Entry, we check whether there are any pending packets to be transmitted when the application is active for a duration of 50ms. If there are pending packets, then it is wrapped up and transmitted as shown below:

pastedImage_0.png

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna

View solution in original post

0 Likes
6 Replies
JayakrishnaT_76
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hello,

Can you please let me know what is the application. Are you trying to establish a loop back between PC and FX3 or just an independent communication?

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

UART TX is used for both debug messages as well as being a data channel to a PC and the UART RX is used to receive commands from a PC.

Eventually the UART channel will be used so the PC can configure and reconfigure the USB peripheral as well as receive some status information.

Currently I am testing RX with simple loop back functionality.

UART TX works great with arbitrary data sizes but receiving arbitrary sizes does not work reliably.

0 Likes

Hello,

Have you tried UsbUart example provided along with FX3 SDK? This project can be found at the following location:

C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\serialif_examples\cyfxusbuart

This example illustrates the use of the FX3 firmware APIs to implement a Virtual COM Port or USB-UART Bridge. The implementation adheres to the CDC-ACM class and allows data communication from USB through to the UART port on the FX3 device. You can test this by connecting the internal debugger to the PC and using 2 Tera Term applications. When Tera Term is opened after loading this firmware, you will have 2 serial ports as shown below:

pastedImage_3.png

Configure one Tera Term using one serial port and the other using the other serial port. Now if you send some data through one Tera term application, it will be seen in the other which shows that data is being received.

This project keeps track of whether the receiver buffer has any pending data or not in the main thread. In the main thread, it checks whether the host has sent some data in the last 50ms. If the host did not send any data in the last 50ms, then the channel is wrapped up and transmitted. The transmitter also works fine. Please check this project and let us know whether it solves your problem or not.

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Hi Jayakrishna,

Thanks for your reply.

This does not solve my problem as the UART producer DMA callback does not occur until the DMA buffer is filled.

I am trying the suggestion from this thread: Cant send a single byte through UART Dma mode !!!

It works and seems reliable so far. However I am slightly worried that it will fail in the future as it is kind of hacky.

Cheers,

Levi

0 Likes

Hello,

According to my understanding you are talking about the DMA channel between UART producer socket and USB consumer socket. Please feel free to correct me if I'm wrong.

If this is the channel, then even if the PROD event does not occur, the buffer will be committed. This is because you can see that in USBUARTAppThread_Entry, we check whether there are any pending packets to be transmitted when the application is active for a duration of 50ms. If there are pending packets, then it is wrapped up and transmitted as shown below:

pastedImage_0.png

Best Regards,

Jayakrishna

Best Regards,
Jayakrishna
0 Likes

Oh ok, I misunderstood the code originally.

This is similar to what I am doing. I will call this settled

0 Likes