Reading single Bytes from UART

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

cross mob
Anonymous
Not applicable

Hi all,

for my Application ( Composite Device UVC + CDC-ACM ) I need to receive single bytes from the FX3 UART and forward them to the appropriate CDC Bulk EP..
Using DMA doesn't work because the data will transferred only if a buffer is filled, what means that at least 16 bytes have to be read.
When using the UART in register mode the function CyU3PUartReceiveBytes(...) seems to Block the whole system for a while if no bytes are available, even if I use it in a separate thread! Is there any possibility to avoid this?

0 Likes
7 Replies
Anonymous
Not applicable

Hi,

   

see FX3ReleaseNotes.pdf file at known issues why DMA mode is not working....

   

7. Any UART/I2C/SPI read transfers in DMA mode that do not fill up the entire DMA buffer will
not trigger a DMA callback or a transfer complete event. The application needs to check for
transfer completion based on the UART/I2C/SPI events and then invoke the
CyU3PDmaChannelSetWrapUp() API on the DMA channel.

   

 

   

For register mode your device on the rx has to send something, otherwise the error code timeout is returned from the function call and with that you may be can handle it.

   

regards,

   

lumpi

0 Likes
Anonymous
Not applicable

I registered an Interrupt callback function with CyU3PRegisterUartCallback().

   

But I do not receive any Events there. The Callback-Function is never called.

   

Do I have to enable UART Interrupt? If yes, how can i do it?

   

Regards

   

frw

0 Likes
Anonymous
Not applicable

 Hi,

   

 

   

You may set the number of bytes to be received using CyU3PUartRxSetBlockXfer API. Aftre you receive so  many number of bytes in UART, as set in CyU3PUartRxSetBlockXfer, you will enter UART callback. We have an example for demonstrating the same. If you would like to get the same, please create a tech support case at www.cypress.com.

   

 

   

Regards,

   

Gayathri

0 Likes
Anonymous
Not applicable

Hi,

   

OK, I receive Interrupts now, After setting CyU3PUartRxSetBlockTransfer( 1 )

   

In my application I use two DMA Auto channels:
One from UART to the USB-CDC Bulk-EP and another one vice versa.
I changed my Application to use the Interrupt callback to call CyU3PDmaChannelSetWrapUp(..).
Now I receive an interrupt and send the Bytes. BUT: One byte received by the UART always stucks in the System and it is only sent, when the next byte is written into the UART. E.g. sending "1234" pause "5" into the UART RX, the Host receives "123" pause "4".
Any Idea how I can Fix it?

Regards
frw

0 Likes
Anonymous
Not applicable

I have been having the same issue and I have some code that is working but I'm not sure how reliable it is. I am still testing.

   

What I did was to setup the UART in DMA mode and also setup an interrupt callback function and use a thread to manage the data if I do not receive enough data for the DMA callback function to be triggered.

   

In the interrupt callback function I check if it is being called because of an RX DONE event and if so I increment a counter and set an event. In my thread it is waiting forever on this event. As soon as the thread wakes up by the event I clear the event. Then I have a do while loop that first saves the current interrupt count and then sleeps for a while (Some amount of time to allow more bytes to be received by the UART. This might depend on your baud rate.). When it wakes up from sleeping it checks if the current interrupt count is the same as it was before sleeping. If it is the same then no more data has arrived and I call the wrapup function. If not the while part quits if the interupt count is zero or after a timeout count. So I only wait for maybe four times in the loop. In the DMA callback function I clear the interrupt counter and do whatever I want with the data. This way if the DMA callback happens while I'm sleeping I will see there is no more data and go back to waiting for the event.

   

The whole idea is that if some data arrives but it's not enough to trigger the DMA callback then I call the wrapup function to cause the DMA callback function to be called and process the data that has arrived. If the DMA callback gets called while waiting for more data then everything worked and we don't need to call the wrapup funciton. Also if more data arrives after the wrapup was called the event will get set so the thread will go back to the begining and do it again.

   

Like I said it is working but I have been told that it's not always reliable. If someone comes up with some new ideas it would be great to hear about them.

   

Thanks,

   

Gary

Trying my luck on this old thread.

I am doing as gaalc_291501 described except I am not using an event; instead I have an infinite loop watching the isr counter and sleeping.

This is sort of working, but less than say 1 out of 1000 bytes sent will get "stuck" in the buffer. I know they are received by the FX3 because the next byte will "dislodge" it and both bytes will be received.

I am testing this with a simple loopback on the FX3 and a PC Application which sends a single byte and waits for the response.

If I ignore the UART ISR and just have an infinite loop call  SetWrapUp and then sleep for 100 ticks I never have an issue with bytes being stuck. This is not a real solution but shows I have set up the UART correctly.

My guess is either the UART ISR does not reliably trigger or perhaps there is a race condition involving the isr counter variable.

So I have two questions.

1) Did you have any issues with race conditions?  I am about to try a mutex/semaphore to control access to the isr count variable to test this myself.

2) Is there a way to read how many bytes are in the receive DMA buffer? This way if the UART isr is unreliable I have a contingency plan.

0 Likes
Anonymous
Not applicable

Trying the examples from the book "SuperSpeed Device - Design by Example", at ch.4 Example 3, where the FX3 is getting simple commands from PC over UART channel, it is supposed to have the uart callback called for each byte, with CyU3PUartRxSetBlockTransfer(1) - not happening !

   

Also, like previous posters mentioned, there are some delays in receiving characters (from HTerm or ClearTerminal) or even missing some - I send "set200\r" and I get echoed "et200" or "t200".

   

I know the main purpose of FX3 is for high-speed USB 3.0 communication, so probably fixing such problem on the UART DMA channel is not high prio for Cypress team; however, developing FW appl. for this FX3 chip, especially following the above book, needs such "back-door channel" for debugging, so.... when and how can we expect a fix from Cypress, please ?

   

Thank you.