cancel
Showing results for 
Search instead for 
Did you mean: 

USB Superspeed Peripherals

Contributor II

Hi All,

A am using CyUSB.dll to communicate with a CX3 vendor project based on this firmware post: https://community.cypress.com/thread/16971?start=0&tstart=0.  I am still having issues transporting images from a 5Mp sensor (see this post https://community.cypress.com/thread/44605), but that isn't the focus of this post.

The firmware has been working reliably as I have been adding new vendor commands to control the various features of our device but I have stumbled into an issue that I can't figure out.  It appears maybe to be a bug in the CyUSB library Read() function.

I have attached four files.  The output from the PC program running the test program, the UART output from firmware with the normal debug statements in the firmware plus many I have added at key points in the firmware routine that's failing.  I also have attached the C function, send_vendor, that the PC program uses to send vendor commands and receive their replies and finally the firmware's CyCx3UvcApplnUSBSetupCB function that implements the vendor commands.

run script.txt shows the PC program's output.  Briefly, the test program issues a series of vendor commands that interrogates the firmware version then sets and interrogates the camera resolution, various test patterns, and finally attempts to use two commands that retrieve buffered data from within the firmware.  The first command, outchrcnt asks the device how many buffered characters there are.  This command returns a single byte indicating the count (0..255).  The second command, devout, asks the device for the buffered data.  I realize that the buffer potentially can be larger than the control endpoint allows, however, for this test the buffered data consists of 7 bytes, and so poses no potential overflow issue.

My issue is the outchrcnt command, and all the others work as I expect them to, but the devout command isn't working.  According to firmware debug messages, the 7-byte buffer *is* correctly transmitted, but accounting to the PC code, it is *never* read (the Read() function in send_vendor() always returns false and buflen is always set to 0).  You'll notice that all of the implemented vendor commands use the same basic form and they all work except devout.  Most puzzling!

I have tried to send fixed messages from within the devout command (instead of retrieving the buffered data) to simplify the situation but these too fail.  I have also tried sending single character replies (instead of multi-character replies), none of this works.

Any thoughts are appreciated.

Thanks,

Scott

0 Likes
Reply
1 Solution
Moderator
Moderator

Hello Scott,

- Can you please use the Streamer application to read data from the CX3 device and use a custom application to just send vendor commands whenever the user intends to? This way, the issue can be isolated as to either with the application layer or with the lower layers.

- Is this issue seen across different OS, different PCs?

- If possible, please share the application over the private message option. I shall try to reproduce the issue at my end.

Best regards,

Srinath S

View solution in original post

0 Likes
Reply
8 Replies
Moderator
Moderator

Hello,

- Please modify the ept -> timeout value from 200 to a higher value, say 2000. This would give sufficient time for all the data to be sent to the host.

- Ensure that rbuf is allocated sufficient space to hold the contents.

Also, from your code, it looks like you are using CyAPI.LIB file but you have mentioned CyUSB.DLL file. Please confirm.

Best regards,

Srinath S

0 Likes
Reply
Contributor II

Hi Srinath,

Thanks for your reply.

I started with a timeout of 2000 and found that the system cannot recover if firmware detects DMA timeouts.  Using 200, the system can repeatedly recover from timeouts.   Here's what I mean by that.

When the PC app starts and issues the start streaming command, firmware will detect multiple DMA timeouts before the system "locks" and can stream video without error.  Streaming continues until some Windows event delays the collection thread by a millisecond or more.  This delay causes firmware to detect a DMA timeout (error 0x47, sequence error).  Using a timeout of 2000, the system will never recover from this timeout until firmware is reloaded.  By reducing the timeout to 200, the system often can recover from the timeout and resume streaming without intervention.  In this configuration, streaming can continue unaided sometimes up to a minute or so.  With a timeout of 2000, it rarely manages to stream more than 20 seconds.

Rbuf is large enough.

I was under the impression that CyAPI.lib is the symbol export library for CyUSB.DLL, is this not the case?

Thanks,

Scott

0 Likes
Reply
Contributor II

Hi All,

No comments on this case?

Thanks,

Scott

0 Likes
Reply
Moderator
Moderator

Hello Scott,

- I tried porting your code (firmware and the host application) into an existing example and I don't find any issues in reading the data.

- Can you please read data using the Cypress Control Center from the control endpoint and check if it is successful?

- Look for the error received on the "Read" API using the GetLastError() function.

- Please capture USB traces during the failure and share the same.

Best regards,

Srinath S

0 Likes
Reply
Contributor II

Hi Srinath,

Yes, control center successfully reads data.  This problem however is a long-term stability issue.  The app and firmware are interacting for a relatively long time before there's a failure.  Several tens of minutes and longer are not uncommon.

I used your suggestion of adding GetLastError() to the PC code.  There are two errors 0x3E3 (operation aborted) and 0x1F (read fault).  I see several 3E3 errors when the PC app first starts and randomly as it runs.  The system recovers from these errors.  3E3 is the type of error I can trigger by adding a random 1 ms delay in the collection thread.  Each random delay triggers one of these errors.

Error 1F is the fatal error.  Once this error is detected all collection stops and the only way I have found to restore operation is to reload the CX3's firmware.  Closing & restarting the PC app doesn't restart collection.  If there was a way for the PC app to detect and recover from this error this problem wouldn't be an issue.

Today I also tried setting my two thread priorities to REALTIME_PRIORITY_CLASS and HIGH_PRIORITY_CLASS, respectively for the collection thread and the rendering threads.  I don't know if this has helped yet.

I don't have a good way to probe the USB bus but especially so due to the intermittent and random nature of this problem.

Thanks for your help,

Scott

0 Likes
Reply
Moderator
Moderator

Hello Scott,

- I tried reproducing the error (Error Code 31) in Windows application by issuing a series of vendor requests to the control endpoint and was able to do so. Upon looking into the traces under this failing condition, I found that there was a STALL condition on the endpoint whenever there was a failure. Anyway, I did not find the application/firmware to be stuck at that point. Subsequent vendor requests were accepted and data transfer was successful. Can you please let me know if your application is coded such that any error on the endpoint would stop the application?

- Another observation was that adding a slight delay (10ms) between the vendor requests did not throw any errors. Please try this at your end let me know if this would be suitable for your application.

- Also, you have mentioned that you use two threads in your application. I understand that one of the threads is for reading the image data whereas the other is for issuing vendor requests. Please let me know if my understanding is correct. If yes, then let me know if the send_vendor function is called continuously from the collection thread or is it intermittent.

Best regards,

Srinath S

0 Likes
Reply
Contributor II

Hi Srinath,

When I see error 31 it is not due to issuing a single or series of vendor commands.  It results from calling the Read() library function in the video collection thread.  In this instance, firmware must be reloaded to recover.

I'll clarify my application.  There are two threads and the main loop running.  One thread does indeed collect video data into multiple frame-sized buffers, the second thread renders the collected video data.  Since the data is transported in RAW 10-bit Bayer format, the rendering thread translates the data into 8-bit BGR format and displays the resulting frames.

The main loop monitors the numbers of collected and displayed frames and periodically (every 10 seconds) prints their numbers.  While video is running, there are generally no vendor commands being set to the CX3.  The exception is when the program terminates, a stop scan (vendor) command is sent to close-down the threads in an orderly manner.

The way my test application is constructed, vendor commands are sent to the CX3 as a result of user keystrokes.  By this I mean the user types a keyboard command that triggers the app to send a vendor command, so pacing them with an additional delay of 10 ms isn't necessary.

Although not the normal case, issuing vendor commands from the main loop will disrupt video processing causing error 31 to happen almost immediately.  When commands are not sent from the main loop, video can stream for 10s of minutes before error (31) shows itself.  The "record" for continuous streaming is a little over 30 minutes.

Thanks for your help,

Scott

0 Likes
Reply
Moderator
Moderator

Hello Scott,

- Can you please use the Streamer application to read data from the CX3 device and use a custom application to just send vendor commands whenever the user intends to? This way, the issue can be isolated as to either with the application layer or with the lower layers.

- Is this issue seen across different OS, different PCs?

- If possible, please share the application over the private message option. I shall try to reproduce the issue at my end.

Best regards,

Srinath S

View solution in original post

0 Likes
Reply