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

cross mob
EZ_Engineer
Level 2
Level 2
10 replies posted 10 sign-ins 5 replies posted

I am looking for an example on how to set up Long_Transfers on the CYUSB3KIT-003. The names of the different firmware examples unfortunately don't mention it. Could use a download or the name of an FX3 example that implements it. 

Much appreciated!

0 Likes
1 Solution
Bakal
Moderator
Moderator
Moderator
100 sign-ins 25 solutions authored 50 replies posted

Hello,

Your understanding regarding AN75779 is correct. 

What do I need to do for the socket to automatically switch to the next DMA buffer when empty?
>> To switch to next DMA buffer you need to add the correct condition in the state machine you can refer to that state machine of AN75779 which includes switching of buffers. 

Please refer to its application note and its stat machine as well : AN75779

Regards,
Sakshi Bakal

View solution in original post

0 Likes
13 Replies
Bakal
Moderator
Moderator
Moderator
100 sign-ins 25 solutions authored 50 replies posted

Hello,

You can use the USBBulkSourceSink example for bulk data transfers. 

Regards,
Sakshi Bakal

0 Likes
EZ_Engineer
Level 2
Level 2
10 replies posted 10 sign-ins 5 replies posted

Hi Sakshi,

Thank you for the quick reply! I am currently taking a look at the USBBulk examples.

That said, the SourceSink example seems to be set up for large USB transfers, discarding all received data immediately, and then writing some random data back to the USB port.

However, my problem is less about bulk transfers from the PC to the FX3 and more about bulk transfers from the FX3 to the GPIF interface. My data exceeds the 32KB size of the P-Port, causing my transaction to get chopped up by the state machine into a large number of incomplete writes, long_transfers seem to be the solution to that.

Do you know of a code example for writing >32KB of data out through the P-Port?

Much appreciated!

0 Likes
Bakal
Moderator
Moderator
Moderator
100 sign-ins 25 solutions authored 50 replies posted

Hello,

Please let me know the following details:

1. Which example code you are currently using?
2. Which GPIF state machine you are using?
3. What is your DMA buffer size?
4. Do share your USB debug prints
"my transaction to get chopped up by the state machine into a large number of incomplete writes":
5. Where did you get to see the chopped data let us know.
6. Also What type of data you are transferring? 

Thank you,
Sakshi Bakal

0 Likes

Hi Sakshi, quick ping that I've posted some additional info below. Not sure if the system lets you know if the Topic's been updated or only if someone specifically replies to you. Cheers!

0 Likes
lock attach
Attachments are accessible only for community members.
EZ_Engineer
Level 2
Level 2
10 replies posted 10 sign-ins 5 replies posted

Hi Sakshi,

Thanks for getting back to me! I'll first answer your questions and then give some additional insight into what it is I am trying to accomplish. My apologies if this is a repeat, I had written a reply earlier but upon reloading the page I am no longer seeing my reply. It doesn't show on my profile, nor if I open the thread in Incognito mode. Not sure what happened there.

To answer your questions:

  1. I am using a modified version of the GPIFtoUSB code that I changed to write data from USBtoGPIF instead, plus some I2C writes to set up the downstream IC. I have attached my code.
  2. The state machine is of my own making. It is included in the data_out.cydsn folder inside the UsbtoGpifModified.zip file.
  3. My DMA buffer size is (640 x 360 x 16). The display I am writing to is 640 pixels wide and 360 lines long and 16bits per pixel. The buffer count is 2. As far as my understanding goes, this should exceed the internal memory of the FX3 but the CyU3PDmaChannelCreate was unhappy with only 1 buffer and didn't complain when I asked for 2 of this size so I just left it at that for now.
  4. I am out of the office today so I will need to share my USB debug prints another time, but as far as I recall there were no errors in the initialization and operation.
  5. I am monitoring the GPIF interface with a Saleae logic analyzer. I have attached the logic capture below. If you'd like to open it you will need the Saleae Software.
  6. I am looking to write RGB565 data to a 640 x 360 display.

Additional information:

I am working to build a USB -> parallel RGB565 bridge that interfaces with a DLPC2607 driving a 640 x 360 display. 16-bit parallel RGB is comprised of 16 data pins, HSYNC, VSYNC, CLK and DATAEN. With my analyzer I am capturing PCLK, HSYNC, VSYNC, DATAEN, DATA[0], and DATA[1].

At a high level,

  • Data is written out in 640 cycle chunks, representing the 640 pixels per line.
  • Each clock cycle clocks out 16 bits (2 bytes) at a time, representing the RGB values for a single pixel.
  • At the beginning of each line, HSYNC is pulled high for at least 4 clock cycles, indicating the beginning of a new line
  • At the beginning of each image, VSYNC is pulled high for 2 empty lines, indicating the beginning of a new frame.

Given this, the expected behavior is that VSYNC goes high for two empty lines, followed by 360 cycles of HSYNC + DATA being written. I have simulated the beginning of a frame write using the GPIF II designer:

EZ_Engineer_0-1678127646825.png

You can see VSYNC asserting for two HSYNCs with no activity on the data bus, followed by 5 lines. Each line is a HSYNC pulse, followed by 640 clock cycles of activity on the DataBus. In simulation this looks like it works quite nicely.

However, when I write (640 pixels/line x 360 lines/frame x 2 bytes/pixel x 1 frame=) 460,800bytes to the FX3 using the Data Transfer on the FX3 Control Center I am seeing the following output captured by the Saleae:

EZ_Engineer_1-1678127874225.png

As you can see, VSYNC asserts many, many times. Instead of just once at the beginning. Zooming in, we can see the following:

EZ_Engineer_2-1678127984932.png

As we can see the frame starts fine, with VSYNC asserting and two empty lines written, however only ~1.6 lines of data are written afterward before VSYNC asserts again, instead of the 360 lines that I want to write.

Data is clocked out at 20Mhz, and both DATAEN blocks combined are 31.844us + 19.048us wide, which yields about 1017 clock cycles of valid data. I suspect that there are some rounding errors in the measurement and that the true number is 1024 cycles.

The total transaction is 26.787ms while each partial transfer is 119.292us long, which yields about 225 transfers. Combined the 225 chunks thus write out (225 chunks x 1024 data_writes/chunk x 2 bytes/data_write  😃 460,800 bytes of data.

So the whole image is being written out. But the transaction is chopped into 2048 byte chunks and in the process becomes unusable for the downstream IC. I suspect that this has something to do with this line from the FX3's programmer's Manual:

EZ_Engineer_3-1678128501555.png

Because the state machine resets when DMA_RDY_0 deasserts, which I assumed it would do if all the data from the buffer has been written out.  My current suspicion is that the P-Port buffer is empty after 2048 bytes have been written and DMA_RDY deasserts as another chunk of 2048 bytes is moved into the buffer, resetting the state machine in the meantime.

Hope this explains the problem well enough.

Thanks! EZ_Engineer

 

 

 

 

0 Likes
lock attach
Attachments are accessible only for community members.
EZ_Engineer
Level 2
Level 2
10 replies posted 10 sign-ins 5 replies posted

Quick update: I have modified the state machine such that it keeps writing data until 640pixels x 360 lines have been written, and from the looks of it, I am now getting a proper VSYNC, followed by 360 HSYNCs:

EZ_Engineer_0-1678481083299.png

However, there's still an issue with the data being written and I think that issue is still related to the size of the P-Port buffers. As you can see, the Data lines only move at the beginning of the transition. Roughly 25 lines + some spares. Measurements place tell me there are 16,465 clock cycles of data being written - so about 32,930 bytes of data. I suspect that the actual number is 32,768, equal to 32KB, the size of the P-Port buffer.

Additionally, after one data transfer of (360 x 640 x 2 ) bytes from the Infineon Control Center any subsequent writes are timing out with "BULK OUT transfer failed with Error Code:997". This suggests that data isn't being consumed by the GPIF block (as discussed in this thread).

My data writes are set to remove data from the source:

EZ_Engineer_1-1678481473725.png

So I'm curious why the buffer is filling up. Any ideas? Thanks!

I've attached the modified state machine to this post.

 

0 Likes

I have also added a callback to printout any errors from the GPIF interface, as discussed in this thread.

The result is that I am receiving a bunch of "CYU3P_PIB_ERR_THR0_RD_UNDERRUN" errors. 

 

0 Likes
Bakal
Moderator
Moderator
Moderator
100 sign-ins 25 solutions authored 50 replies posted

Hello,

You are getting the CYU3P_PIB_ERR_THR0_RD_UNDERRUN error because you are reading beyond the available data size on one of the Thread 0 sockets. 

Also what you can try is rather than increasing more than 32KB for a single transfer you can send continuous 32KB data in multiple transfers using 2 sockets similar to UVC transfers in AN75779 having Ping-pong DMA buffers. which will send the data simultaneously without causing any loss or delay in a cycle. 

Best Regards,
Sakshi Bakal

0 Likes
lock attach
Attachments are accessible only for community members.

Hi Sakshi,

I appreciate the reply. I've looked into AN75779 and it does look promising, but there are a few questions I have:

  1. AN75779 uses two of the counters to track when a thread has filled its buffer and to switch to the other one. In my current state machine, however, I am already using all three counters to track the numbers of pixels, the numbers of lines and number of empty lines I've written. Is there an alternate way of keeping track of the amount of bytes remaining in the buffer? I am thinking I might be able to use the Watermark feature with the threshold level set to 0, does that sound reasonable?
  2. My current thinking is that this is a ONE_TO_MANY application. There is one producer (CY_U3P_UIB_SOCKET_PROD_1) and two consumers (CY_U3P_PIB_SOCKET_0, CY_U3P_PIB_SOCKET_1). The producer fills the DMA buffers and then the consumers take turns writing the data to the GPIF interface. Is that the correct understanding? I am asking mostly because of the next question:
  3. When I add a DR_DATA data statement to my state machine that writes data from Thread1 and I connect it to the state machine containing the DR_DATA writes from Thread0 I get the error: "'Thread Number' in action 'DR_DATA' of state 'WRITE_LINE_T0' need to be the same as 'Thread number' of action 'DR_DATA0' in state-'WRITE_LINE_T1'." AN75779 was switching between different threads when reading IN_DATA but that was GPIF writing to multiple buffers. Could it be that the GPIF port only has one socket we can write to?

I've attached the state machine below. The transitions between WRITE_LINE_T0 and WRITE_LINE_T1 are placeholders for now until I can work out the mechanism to switch from one socket to the other.

0 Likes

A quick test shows that GPIF Designer also requires IN_DATA blocks to write using the same thread. I think it's related to this problem, which the solution there was that your colleague Ajeeth modified the cygpif2config.h file. Is that the path forward here as well?

0 Likes

I am thinking the most straightforward method would be to allocate X-lines worth of buffer and then specify multiple buffers for the USB and P-Port to fill/empty.

This does incur the 1 cycle penalty, but there are many times in this interface where control signals need to be asserted/deasserted for a few cycles without any data being written to the bus so I can comfortably switch DMA buffers in those moments.

I changed the buffer size to be a multiple of a single line (640 pixels/line x 2 bytes/pixel x 4 lines) and allocated 4 buffers. Problem is though, that the P-Port still only seems to write out the first buffer. What do I need to do for the socket to automatically switch to the next DMA buffer when empty?

0 Likes
Bakal
Moderator
Moderator
Moderator
100 sign-ins 25 solutions authored 50 replies posted

Hello,

Your understanding regarding AN75779 is correct. 

What do I need to do for the socket to automatically switch to the next DMA buffer when empty?
>> To switch to next DMA buffer you need to add the correct condition in the state machine you can refer to that state machine of AN75779 which includes switching of buffers. 

Please refer to its application note and its stat machine as well : AN75779

Regards,
Sakshi Bakal

0 Likes

Hi Bakal!

I played around with AN75779 a bit and have made some progress. It looks like I have more than one socket worth of data moving now.

I'll accept this answer as the solution and just open a new thread if more questions should come up. Thanks!

0 Likes