Cypress Perform

Home > Design Support > Cypress Developer CommunityTM > Cypress Forums > USB Controllers > EZ-USB/CyAPI Speed Problem

Bookmark and Share
Cypress Developer CommunityTM
Forums | Videos | Blogs | Training | Rewards Program | Community Components



EZ-USB/CyAPI Speed Problem
Moderator:
RSKV

Post Reply
Follow this topic



EZ-USB/CyAPI Speed Problem

jpkiessling posted on 08 Apr 2010 4:09 AM PST
Member
3 Forum Posts

Hi,

my current project is to establish an USB connection between a WinXP PC and an FPGA. I don't get my hands dirty on the FPGA though, my boss does this stuff. He needs me to provide datarate of at least 15 MB/s. I've got a board which has "Cypress semiconductor CY3684 / 3674 EZ-USB Advanced development board" printed on and a "CY7C68013A-128AXC 0731 B 04 645490" chip mounted. I use this to develop my WinXP software (MS Visual C++) but the final version will use an FPGA Board from AVnet. The current firmware for the CY7 USB-Controller is the bulkloop.hex deliverd in c:/cypress/usb/examples.

Right now I use the CyAPI and I'am able to establish a connection to the board, get some informations like "number of endpoints" and bulk transfer in and out. To meassure the tranferspeed I use . (source file is attached) Unfortunatly I only get about 1 MB/s. ( I've tried using http://www.cypress.com/?docID=4383 to meassure speed but I can't get it running. It's probably because I use "USB Console" instead of "EZ-USB Control Panel" which I can't find anywhere. )

So ... where is my bottleneck? Is CyAPI in general unable to attain high bandwidth? Do I use it wrong or is it just the expample firmware that doesn't deliver? Do you have any app notes or other must-reads?

have a nice day,
Jan


PS: this is crossposted in http://www.edaboard.com/thread188074.html (code is way better to read there, due to working [code]

PPS: lol, no *.cpp or *.txt attach allowed?

//***********************************************************
//***********************************************************
//
// File: Test_CyAPI.cpp
// Date: 7.4.10
// Author: Kießling, Jan P.
// Purpose: getting used to CyAPI and writing basic
// functions
//***********************************************************
//***********************************************************



//***********************************************************
// Includes
//***********************************************************
#include
#include
//#include
#include
#include
#include
#include
#include
#include

//***********************************************************
// Macros and Global Variables
//***********************************************************
using namespace std;
extern HANDLE Handle;
using std::string;
//***********************************************************
// Declarations
//***********************************************************
bool USBSend512(unsigned char *out, CCyUSBDevice *USBDevice);
bool USBGet512(unsigned char *in, CCyUSBDevice *USBDevice);
void wait_seconds(int seconds);
[code]
//***********************************************************
// main
//***********************************************************
void main (void)
{
// [USB Init]
CCyUSBDevice *USBDevice = new CCyUSBDevice(NULL);
// Attempt to open device #0
if (USBDevice->DeviceCount() && !USBDevice->Open(0)) // check if there is a device available and if device0 is NOT already open
{
cout << "Resetting and opening Device 0" << endl;
USBDevice->Reset();
USBDevice->Open(0);
}
if (! USBDevice->IsOpen())
{
printf("\n Device NOT open\n\n");
}
else
{
printf("\n Device open\n\n");
}

// [get information]
int devices = USBDevice->DeviceCount();
int altInt = USBDevice->AltIntfcCount();
int curInt = USBDevice->AltIntfc();
int eptCount = USBDevice->EndPointCount();
int maxPaketSize = USBDevice->BulkOutEndPt->MaxPktSize;

// [print information]
cout << "FriendlyName: " << USBDevice->FriendlyName << endl;
//cout << "Number of Cypress Devices: " << devices << endl;
cout << "Number of alternate interfaces: " << altInt << endl;
cout << "Using Interface: " << curInt << endl;
cout << "Number of Endpoints: " << eptCount << endl;
cout << "Max Paket Size of Bulk Out 1: " << maxPaketSize << endl;
cout << "Xfer Size = " << USBDevice->BulkOutEndPt->GetXferSize() << endl;

// [report all Endpoints with type and direction]
string direction, type;
for(int c = 0; c < eptCount; c++)
{
if(USBDevice->EndPoints[c]->bIn)
{
direction = "Input";
}
else
{
direction = "Output";
}
switch(USBDevice->EndPoints[c]->Attributes)
{
case 0:
type = "Control";
break;
case 1:
type = "Isochronous";
break;
case 2:
type = "Bulk";
break;
case 3:
type = "Interrupt";
break;
}
cout << "Endpoint " << c << " is " << type << " " << direction << endl;
}

//[Speed Test]
unsigned char out[512];
unsigned char in[512];
time_t t_start, t_end;
double t_elapsed;
//init arrays
for (c = 0; c < 513; c++)
{
out[c] = 0x00+c;
in[c] = 0x01;
}
//start test
time(&t_start); //get current time
for(double ac=0; ac < 65535; ac++)
{
USBSend512(out, USBDevice);
USBGet512(in, USBDevice);
}
time(&t_end);
t_elapsed = difftime(t_end,t_start);
cout << " " << t_elapsed << endl;
//[are the last two arrays equal?]
bool ka = TRUE;
for(c = 0; c < 512; c++)
{
if(in[c] != out[c])
{
ka = FALSE;
}
}
if(ka)
{
cout << "In equals Out" << endl;
}
else
{
cout << "In doesn't equal Out" << endl;
}
//[End of Main]
USBDevice->Close();
return;
}

//***********************************************************
// functions
//***********************************************************

bool USBSend512(unsigned char *out, CCyUSBDevice *USBDevice)
{
//this function sends 512 Bytes via USB to an open Endpoint
//returns TRUE if OK, false if no EP exists
bool OK = FALSE;
LONG length = 512;

if (USBDevice->BulkOutEndPt) //check if EP exists
{
OK = (USBDevice->BulkOutEndPt->XferData(out, length)); //sending array
}
else
{
OK = FALSE;
}
return OK;
}
//***********************************************************
bool USBGet512(unsigned char *in, CCyUSBDevice *USBDevice)
{
//this function gets 512 Bytes via USB from an open Endpoint
//returns TRUE if OK, false if no EP exists
bool OK = FALSE;
LONG length = 512;

if (USBDevice->BulkInEndPt) //check if EP exists
{
OK = USBDevice->BulkInEndPt->XferData(in, length);
}
else
{
OK = FALSE;
}
return OK;
}
//***********************************************************
void wait_seconds(int seconds)
{
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC ;
while (clock() < endwait)
{

}
}
[/code]




Re: EZ-USB/CyAPI Speed Problem

jpkiessling posted on 09 Apr 2010 07:36 AM PST
Member
3 Forum Posts

I'm confident that I solved the problem. Seems a little to good to be true though.

I've changed the firmware to bulksrc.hex which delivers/consumes infinite amount of data. I assume that this happens by setting/clearing some kind of ready flag. Thus the 8051 doesn't take time to read or load the endpoints. This change alone gave me a lot of speed.

The other point is that I used SetXferSize( ) to set it from 0x200 to FFFF. I'm not sure what it exactly does but an appnote recommends it.

Third point is the usage of XferData(). I used to transfer 512 Byte big arrays ... which is only one measly USB packet. Now with each call of this method I hand it a pointer to a FFFF big char array (representing 128 packets). Reading 10000 of these takes me 16 seconds and that'd be around 41 MB/s.

Reading 100000 takes 162 seconds.

Re: EZ-USB/CyAPI Speed Problem

aasi posted on 13 Jan 2012 09:32 PM PST
Cypress Employee
1090 Forum Posts

Just wanted to give you explanation for each of your change

1. Bulkloop uses the 8051 to transfer data from endpoint to another (comparing with USB2.0 speed 8051 is very slow, putting it in the datapath will slow down traffic)

2. SetXferSize() is used to set the amount of buffer allocated in host controller driver for the device (For example: If I allocate a 1k buffer, for a 4k transfer the host controller buffer will fill up 4 times and 3 times the host controller would have waited for the OS to read and then clear the buffer. Instead say I use a 4k buffer there is no waiting i.e. more speed). This has its own restriction based on Windows http://msdn.microsoft.com/en-us/library/ff538112.aspx.

3. Similar to above between each Xferdata() time is needed since the OS has to queue and schedule the next Xferdata(). If you use the Asynchronous approach (Beginxferdata/waitforxfer/Finishxferdata) the transfers are queued so the next transfer is queued before the first transfer completes. You should be able to get a slightly higher speed with it. You can use Streamer/screamer example that comes as part of SuiteUSB as reference to implement this.

Regards,

Anand

 






ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". CYPRESS SEMICONDUCTOR AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY CYPRESS SEMICONDUCTOR. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM CYPRESS SEMICONDUCTOR.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms and Conditions of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms and Conditions of this site. Cypress Semiconductor and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

Spec No: None; Sunset Owner: KXP; Secondary Owner: VWA; Sunset Date: 01/01/20