USB superspeed peripherals Forum Discussions
Hi,
I am trying to reconfigure the descriptors in the USBIsoSourceSink example because I want to increase the throughput in isochronous mode.
The isochronous throughput depends on
service interval = 1 (default) = each 125uS
maxpacketsize = 0x400 (default) = refer to USB spec, must be on 1024 for isochronous when we are going to set bMaxBurst (and we are)
bMaxBurst = MaxBurst -1, MaxBurst: The number of packets the endpoint can send or receive as part of a burst (range 1 - 16)
bmAttributes.mult = BurstMult -1, BurstMult: The number of bursts in the service interval (range 1 - 3 for isochronous)
This all combined leads to a value for wBytesPerinterval
In the USBIsoSourceSink example I changed the define CY_FX_EP_BURST_LENGTH from 1 to 2 to set the MaxBurst value in the endpoint descriptors. Ignoring the wBytesPerinterval (both ignoring and not ignoring this leads to the same results), I have trouble increasing the throughput and experience crashes of the driver.
What I observe is that it appears the API multiplies the wMaxPacketSize with the MaxBurst value
********** A **************
Original (decoded by USB Control Center / API):
CY_FX_EP_BURST_LENGTH = 1
<ENDPOINT>
Type="ISOC"
Direction="OUT"
Address="01h"
Attributes="01h"
MaxPktSize="1024" <<<<<<<<<< expected
DescriptorType="5"
DescriptorLength="7"
Interval="1"
<SUPER SPEED ENDPOINT COMPANION>
Type="SUPERSPEED_USB_ENDPOINT_COMPANION"
bMaxBurst="0" <<<<<<<<<<
Attributes="00h"
BytesPerInterval="400h"
</ENDPOINT>
********** B ***********
After changing MaxBurst from 1 to 2 (Note bMaxBurst = MaxBurst -1 = 1):
CY_FX_EP_BURST_LENGTH = 2
<ENDPOINT>
Type="ISOC"
Direction="OUT"
Address="01h"
Attributes="01h"
MaxPktSize="2048" <<<< multiplied by 2 (not expected)
DescriptorType="5"
DescriptorLength="7"
Interval="1"
<SUPER SPEED ENDPOINT COMPANION>
Type="SUPERSPEED_USB_ENDPOINT_COMPANION"
bMaxBurst="1" <<<<
Attributes="00h"
BytesPerInterval="400h"
</ENDPOINT>
Observation: MaxPktSize appears to be multiplied by MaxBurst
********** C ************
As a reference the decoding descriptor by "Thesycon USB Descriptor Dumper":
CY_FX_EP_BURST_LENGTH = 2
Endpoint Descriptor:
------------------------------
Value Valuename
0x07 bLength
0x05 bDescriptorType
0x01 bEndpointAddress (Out-Endpoint)
0x01 bmAttributes
Transfer Type: Isochronous-Transfer
Synchronization Type: None
Usage Type: Data
0x0400 wMaxPacketSize (1024 Bytes) <<<<< still 1024 (expected)
0x01 bInterval
Hex dump:
0x07 0x05 0x01 0x01 0x00 0x04 0x01
SuperSpeed Endpoint Companion Descriptor:
------------------------------
Value Valuename
0x06 bLength
0x30 bDescriptorType
0x01 bMaxBurst (2 packet(s)) <<<<
0x00 bmAttributes
0x0400 wBytesPerInterval (1024 Bytes)
observation: the wMaxPacketSize is reported unchanged and is 1024 bytes as specified by the firmware
********** D ************
After changing MaxBurst from 1 to 8 (Note bMaxBurst = MaxBurst -1 = 7):
CY_FX_EP_BURST_LENGTH = 8
<ENDPOINT>
Type="ISOC"
Direction="OUT"
Address="01h"
Attributes="01h"
MaxPktSize="8192" <<<< multiplied by 8 (not expected)
DescriptorType="5"
DescriptorLength="7"
Interval="1"
<SUPER SPEED ENDPOINT COMPANION>
Type="SUPERSPEED_USB_ENDPOINT_COMPANION"
MaxBurst="7" <<<<<
Attributes="00h"
BytesPerInterval="400h"
</ENDPOINT>
Observation: MaxPktSize appears to be multiplied by MaxBurst
********** E *************
As a reference the decoding descriptor by "Thesycon USB Descriptor Dumper":
CY_FX_EP_BURST_LENGTH = 8
Endpoint Descriptor:
------------------------------
Value Valuename
0x07 bLength
0x05 bDescriptorType
0x01 bEndpointAddress (Out-Endpoint)
0x01 bmAttributes
Transfer Type: Isochronous-Transfer
Synchronization Type: None
Usage Type: Data
0x0400 wMaxPacketSize (1024 Bytes) <<<<< expected
0x01 bInterval
Hex dump:
0x07 0x05 0x01 0x01 0x00 0x04 0x01
SuperSpeed Endpoint Companion Descriptor:
------------------------------
Value Valuename
0x06 bLength
0x30 bDescriptorType
0x07 bMaxBurst (8 packet(s)) <<<<<
0x00 bmAttributes
0x0400 wBytesPerInterval (1024 Bytes)
observation: the wMaxPacketSize is reported unchanged and is 1024 bytes as specified by the firmware
*********** F *************
So it appears the API multiplies the wMaxPacketSize with the MaxBurst value. Is this correct behaviour?
Show LessHi
I use the following this method tried to reset a DMA channel in the slave sync fifo example
CyU3PDmaChannelReset(&glChHandleSlFifoPtoU);
/* Flush the Endpoint memory */
CyU3PUsbFlushEp(CY_FX_EP_CONSUMER);
/* Set DMA channel transfer size. */
CyU3PDmaChannelSetXfer (&glChHandleSlFifoPtoU, CY_FX_SLFIFO_DMA_TX_SIZE);
In USB2.0 mode is executed with operation no problem,But in USB3.0 mode will be a mistake .how to solve?
Regards,
lian.
Show LessWe have an issue when we want to use a pin in GPIO mode for a short while, then release it and use as a part of GPIF. According to docs we need to call CyU3PDeviceGpioOverride, then release it with CyU3PDeviceGpioRestore. We do all that and it works as expected while in GPIO mode, however, GPIF failes to control the pin afterwards.
Our GPIF II state machine behaves properly - we verified it in a special case when we never call CyU3PDeviceGpioOverride.
However, as soon as we call CyU3PDeviceGpioOverride/CyU3PDeviceGpioRestore, GPIF fails to obtain the control of the pin. Regardless of when we call CyU3PGpifLoad (after of before CyU3PDeviceGpioRestore).
Any help?
Show LessSo I've got an application with a GPIF waveform that worked fine in V1 of the libraries but does not in V1.1 or 1.1.1 (although the upgraded libraries fix other issues I had with spi i2c gpio etc.).
The mechanism should transfer data from an out endpoint via an Auto DMA channel to the gpif which transfers out of an 8 or 16bit interface. The GPIF is running at 50MHz, Master, and the transition from wait to data out is defined as "(!BUSY)&(DMA_RDY_TH3)" where busy is an external input pin. The DMA is receiving data and filling buffers but the consumer CY_U3P_PIB_SOCKET_3 doesn't take any data. I beleive this is because the DMA_RDY_TH3 flag is never asserted having observed it on an output pin, the same is true of the WM flag or the current thread flags, none seem to toggle which they do from builds with V1 library. I have tried using this DMA as a manual channel and commiting the data manually using the CyU3PDmaChannelCommitBuffer function which returns success but I still get no data transferred out of the GPIF or any flags changing state.
Has anyone had this issue or possibly hit on a solution.
Show LessI am used to dealing with microcontrollers where the USB data is put into an array that can be accessed at the byte level. So you call a doUSB() function, you get a 64byte packet of data from the host, process, and send back a 64byte packet. Or receive a byte array all the time and then send out byte arrays all the time by just checking if the endpoint is clear to do so or not.
So looking at the FX3 sample code is daunting. I can make the GPIO sample wiggle a PWM pin and so it works.
But now I just want to be able to pass the information out of the USB module into a peripheral and into another chip like an FPGA to do some light work and pass it pack through the peripheral and back into the USB module. Like a FIFO in for USB data from the host to the device and a FIFO out for USB data from the device to the host.
Since there are impossibly tiny Samtech and Tyco connectors on the dev board to access the Slave FIFO, I am forced to use the SPI header. I read that it can go 33MHz which is fine for initial testing. I am hoping I can move to the slave FIFO once I get an actual board spun with an FPGA and the FX3 on it. But for now it will be 2 dev kits wired together with some jumper wire.
So back to the firmware, I am looking at the USBSpiRegMode example (although I still dont understand the difference between RegMode and DMA mode) because it seems like a good base to go from USB to SPI. I don't know if I know what I am looking at.
I see uint8_t glEp0Buffer[4096]; which appears to be Endpoint 0's byte array buffer. Is that correct?
It also looks like the USB mode is not a Write-then-Read architecture but an architecture that splits the write and reads from the endpoint into separate entitites so that you could write forever without reading or visa versa read forever without writing. Correct?
It would appear that CyU3PUsbGetEP0Data() is the magic USB goo that checks the USB endpoint from the host to the FX3 and when there is data it will return the data in the buffer, correct?
So this bit of code...
status = CyU3PUsbGetEP0Data (length, glEp0Buffer, NULL);
...gets "length" bytes from EndPoint 0 (EP0) and puts them into glEp0Buffer, with returned_data's index-0 at glEp0Buffer's index-0? Is this a blocking call until data is received or does it fail the status if there is nothing to read?
Then to transfer on the Spi peripheral it uses this bit of code immediately afterwards correct?
if (status == CY_U3P_SUCCESS)
{
status = CyFxSpiTransfer (index, length,
glEp0Buffer, CyFalse);
}
break;
It would also appear that to send data over USB, you would call CyU3PUsbSendEP0Data(length, buffer pointer) correct?
So would it stand to reason that I could simple stay in a loop that called CyU3PUsbGetEP0Data() and get a byte stream back that I could then pass into CyFxSpiTransfer() for the Host->FPGA communication? Then pass that returned SPI byte array into CyU3PUsbSendEP0Data() for the FPGA->Host communication?
Any help would be appreciated.
Show LessHello,
Upfront, I have never worked with the Cypress parts (or ARM with an RTOS) but have lots of "regular" FPGA and MCU (PICs) experience. So I should be able to follow your advice, but currently I just don't know where to start or look to begin with to get me going. Or even if this is possible.
My current hardware is the FX3 USB Developement Kit. I don't specifically need USB 3.0, but I do need high-speed 2.0 instead of the fullspeed 2.0 my project currently has.
The first part of my need is a USB to I2C translator. I need to send a bulk transfer to the device, decode these bytes, and wiggle the I2C line. Then when things are received by the I2C line, re-encode, and send back through another bulk transfer endpoint. The second need is to monitor all edges of the I2C and decode all I2C traffic independently. Currently I have all this working and implemented in a standard PIC32 overclocked (120MHz/120MIPS). So I am hoping with the regular 200Mhz/200MIPS I can get something similar working even if the speed improvement is minimal. I am essentially maxed out with the PIC, hence the move.
So architecturally, does this even work? Can I use the built in MCU to write my firmware? I would suspect so. How much slower is slower when the MCU interprets every USB data transfer? Using the standard stream demo I can get 8MB per second. Is the interrupt overhead large? On the PIC it is 12, so interrupting on every rising and falling edge of an IO pin was expensive, but doable. I am hoping to cut that down, but am unfamiliar with the interrupt scheme used, or if that is even required. If I can poll the signal fast enough, that should be OK (400KHz maximum).
Or should I just be using the part as a passthrough and routing the packets to some large parallel bus and then another FPGA later in the stream? If possible, keeping it on one chip would be nice especially given the cost.
Show LessHello,
can somebody explain why the main thread in the sourcesink example is trying each 2 seconds to get the LPM back to U0?
With that code snippet:
/* Try to get the USB 3.0 link back to U0. */
{
CyU3PUsbLinkPowerMode curState;
if (CyU3PUsbGetSpeed () == CY_U3P_SUPER_SPEED)
{
/* If the link is in U1/U2 states, try to get back to U0. */
stat = CyU3PUsbGetLinkPowerState (&curState);
while ((stat == CY_U3P_SUCCESS) && (curState >= CyU3PUsbLPM_U1) && (curState <= CyU3PUsbLPM_U3))
{
CyU3PUsbSetLinkPowerState (CyU3PUsbLPM_U0);
CyU3PThreadSleep (1);
stat = CyU3PUsbGetLinkPowerState (&curState);
}
}
}
For what use is this?
Why polling each two seconds?
Why not doing this in the LPM callback function if the LPM state changes to other than U0?
Thanks,
lumpi
Show Less