Data loss in isochronous end point
ireshaa_2909251 Jun 7, 2018 6:11 AMHi..
I have implemented a GPIF II interface using an FPGA spartan 6 (XC6SLX9) and a Cypress FX3 (CYUSB3013) controller.
An Isochronous USB endpoint is configured to trasfer the data from the Cypress FX3 to a host PC.
The average data generate rate of the FPGA is about 75Mbps which is generated as distributed chunks rather than as a constant rate data stream. However, I am losing a significant amount of data at the host PC allication.
Followng are some details on my sytsem setup.
PCLK = 60Mhz ; (PCLK is driven by FPGA)
FX3 system clock = 403.2 Mhz; (setSysClk400 = true)
GPIF clock = 100 Mhz ; (pibClock.clkDiv = 4)
USB end point type :- Isochronous
*FX3 Firmware
CY_FX_ISO_BURST = 15;
CY_FX_ISO_PKTS = 1;
epcfg.enable = CyTrue;
epcfg.epType = CY_U3P_USB_EP_ISO;
epcfg.burstLen = CY_FX_ISO_BURST;
epcfg.streams = 0;
epcfg.pcktSize = 1024;
epcfg.isoPkts = 1;
dma_cfg.size = ((1024 + 0x0F) & ~0x0F);
dma_cfg.size *= CY_FX_ISO_BURST;
dma_cfg.count = 8;
dma_cfg.prodSckId = CY_U3P_PIB_SOCKET_0;
dma_cfg.consSckId = CY_U3P_UIB_SOCKET_CONS_2;
dma_cfg.dmaMode = CY_U3P_DMA_MODE_BYTE;
dma_cfg.notification = CY_U3P_DMA_CB_CONS_EVENT;
dma_cfg.cb = 0;
dma_cfg.prodHeader = 0;
dma_cfg.prodFooter = 0;
dma_cfg.consHeader = 0;
dma_cfg.prodAvailCount = 0;
<ENDPOINT>
Type="ISOC"
Direction="IN"
Address="82h"
Attributes="01h"
MaxPktSize="15360"
DescriptorType="5"
DescriptorLength="7"
Interval="4"
<SUPER SPEED ENDPOINT COMPANION>
Type="SUPERSPEED_USB_ENDPOINT_COMPANION"
MaxBurst="14"
Attributes="00h"
BytesPerInterval="3C00h"
</ENDPOINT>
*PC application code to read usb
LONG length = 1024 * 15 * 8 * 64;
std::shared_ptr<uint8_t> image_buffer = std::shared_ptr<uint8_t>(new uint8_t[length]);
QueueSize = int(length / (iso_ep->MaxPktSize * 8));
if ((length % (iso_ep->MaxPktSize * 8)) > 0)
QueueSize++;
for (int j = 0; j < QueueSize; j++){
long len = length / (QueueSize);
std::unique_ptr<uint8_t[]> image_data = std::unique_ptr<uint8_t[]>(new uint8_t[len]);
iso_ep->TimeOut = 5000;
int pkts;
CCyIsoPktInfo * pktInfos;
pktInfos = iso_ep->CreatePktInfos(len, pkts);
if (iso_ep->XferData(image_data.get(), len, pktInfos)){
for (int i = 0; i < pkts; i++){
if (pktInfos[i].Status == 0 && pktInfos[i].Length>0)
{
memcpy(&image_buffer[success * iso_ep->MaxPktSize], &image_data[i * iso_ep->MaxPktSize], iso_ep->MaxPktSize);
success = success + 1;
}
}
}
delete[] pktInfos;
}
length = success * iso_ep->MaxPktSize;