forked from len0rd/rockbox
		
	git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15758 a1c6a512-1295-4272-9138-f99709370657
		
			
				
	
	
		
			212 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			212 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
| 	LPCUSB, an USB device driver for LPC microcontrollers	
 | |
| 	Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
 | |
| 
 | |
| 	This library is free software; you can redistribute it and/or
 | |
| 	modify it under the terms of the GNU Lesser General Public
 | |
| 	License as published by the Free Software Foundation; either
 | |
| 	version 2.1 of the License, or (at your option) any later version.
 | |
| 
 | |
| 	This library is distributed in the hope that it will be useful,
 | |
| 	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| 	Lesser General Public License for more details.
 | |
| 
 | |
| 	You should have received a copy of the GNU Lesser General Public
 | |
| 	License along with this library; if not, write to the Free Software
 | |
| 	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | |
| */
 | |
| 
 | |
| /*
 | |
| 	Simple benchmarking application.
 | |
| 	
 | |
| 	It talks with the 'custom' device application on the LPC214x through
 | |
| 	libusb.
 | |
| 
 | |
|         2007-11-01: Some minor modifications by <bjorn@haxx.se>
 | |
| 
 | |
| */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <unistd.h>
 | |
| #include <sys/timeb.h>
 | |
| 
 | |
| #include "usb.h"
 | |
| 
 | |
| // types
 | |
| #ifndef MIN
 | |
| #define MIN(a,b)	((a)<(b)?(a):(b))
 | |
| #endif
 | |
| typedef unsigned int U32;
 | |
| typedef unsigned char U8;
 | |
| 
 | |
| #define MAX_TIME 3000
 | |
| 
 | |
| static unsigned char abData[16384];
 | |
| 
 | |
| // USB device specific definitions
 | |
| #define VENDOR_ID	0x0781
 | |
| #define PRODUCT_ID	0x7450
 | |
| 
 | |
| #define	BM_REQUEST_TYPE		(2<<5)
 | |
| #define BULK_IN_EP			0x82
 | |
| #define BULK_OUT_EP			0x05
 | |
| 
 | |
| // this structure should match with the expectations of the 'custom' device!
 | |
| typedef struct {
 | |
| 	U32		dwAddress;
 | |
| 	U32		dwLength;
 | |
| } TMemoryCmd;
 | |
| 
 | |
| 
 | |
| static struct usb_device * find_device(int iVendor, int iProduct)
 | |
| {
 | |
| 	struct usb_bus	*usb_bus;
 | |
| 	struct usb_device *dev;	
 | |
| 	
 | |
| 	for (usb_bus = usb_get_busses(); usb_bus; usb_bus = usb_bus->next) {
 | |
| 		for (dev = usb_bus->devices; dev; dev = dev->next) {
 | |
| 			if ((dev->descriptor.idVendor == iVendor) && 
 | |
| 				(dev->descriptor.idProduct == iProduct)) {
 | |
| 				return dev;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return NULL;
 | |
| }
 | |
| 
 | |
| 
 | |
| static struct timeb start;
 | |
| 
 | |
| static void starttimer(void)
 | |
| {
 | |
| 	ftime(&start);
 | |
| }
 | |
| 
 | |
| static int stoptimer(void)
 | |
| {
 | |
| 	struct timeb now;
 | |
| 	
 | |
| 	ftime(&now);
 | |
| 	return 1000 * (now.time - start.time) + now.millitm - start.millitm;
 | |
| }
 | |
| 
 | |
| 
 | |
| int main(void)
 | |
| {
 | |
|     const int blocksize[] = { 128, 512 };
 | |
| 	struct usb_device *dev;	
 | |
| 	struct usb_dev_handle *hdl;
 | |
| 	int i, j;
 | |
| 	U32 dwBlockSize, dwChunk, dwBytes;
 | |
| 	TMemoryCmd MemCmd;
 | |
| 	int iTimer;
 | |
| 
 | |
| 	usb_init();
 | |
| 	usb_find_busses();
 | |
| 	usb_find_devices();
 | |
| 	
 | |
|         for (i=0; i<sizeof abData/4; i++)
 | |
|             ((unsigned int*)abData)[i] = i;
 | |
| 
 | |
| 	dev = find_device(VENDOR_ID, PRODUCT_ID);
 | |
| 	if (dev == NULL) {
 | |
| 		fprintf(stderr, "device not found\n");
 | |
| 		return -1;
 | |
| 	}
 | |
| 	
 | |
| 	hdl = usb_open(dev);
 | |
| 	
 | |
| 	i = usb_set_configuration(hdl, 1);
 | |
| 	if (i < 0) {
 | |
| 		fprintf(stderr, "usb_set_configuration failed\n");
 | |
| 	}
 | |
| 	
 | |
| 	i = usb_claim_interface(hdl, 0);
 | |
| 	if (i < 0) {
 | |
| 		fprintf(stderr, "usb_claim_interface failed %d\n", i);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	// read some data
 | |
| 	for (j = 0; j < 1; j++) {
 | |
|                 dwBlockSize = blocksize[j];
 | |
| 		fprintf(stderr, "Testing blocksize %5d\n", dwBlockSize);
 | |
| 
 | |
| #if 1
 | |
| 		fprintf(stderr, "* write:");
 | |
| 		// send a vendor request for a write
 | |
| 		MemCmd.dwAddress = 0;
 | |
| 		MemCmd.dwLength = 20 * 1024;
 | |
| 		i = usb_control_msg(hdl, BM_REQUEST_TYPE, 0x02, 20, 1024, NULL, 0, 1000);
 | |
| 		if (i < 0) {
 | |
| 			fprintf(stderr, "usb_control_msg failed %d\n", i);
 | |
|                         break;
 | |
| 		}
 | |
| 		dwBytes = 0;
 | |
| 		starttimer();
 | |
| 		while (MemCmd.dwLength > 0) {
 | |
| 			dwChunk = MIN(dwBlockSize, MemCmd.dwLength);
 | |
| 			i = usb_bulk_write(hdl, 0x01, (char *)abData, dwChunk, 2000);
 | |
| 			if (i < 1) {
 | |
| 				fprintf(stderr, "usb_bulk_write failed %d\n", i);
 | |
| 				break;
 | |
| 			}
 | |
| 			MemCmd.dwLength -= dwChunk;
 | |
| 			dwBytes += dwBlockSize;
 | |
| 			if (stoptimer() > MAX_TIME) {
 | |
| 				break;
 | |
| 			}
 | |
|                         ((unsigned int*)abData)[0]++;
 | |
|                 }
 | |
|                 if (i<0)
 | |
|                     break;
 | |
| 		iTimer = stoptimer();
 | |
|                 if (iTimer)
 | |
|                     fprintf(stderr, " %7d bytes in %d ms = %d kB/s\n", dwBytes, iTimer, dwBytes / iTimer);
 | |
| 		// stdout
 | |
| 		printf("%d,%d,%d\n", dwBlockSize, dwBytes, iTimer);
 | |
| #endif
 | |
| #if 1
 | |
| 		fprintf(stderr, "* read :");
 | |
| 		// send a vendor request for a read
 | |
| 		MemCmd.dwAddress = 0;
 | |
| 		MemCmd.dwLength = 20 * 1024;
 | |
| 		i = usb_control_msg(hdl, BM_REQUEST_TYPE, 0x01, 20, 1024, NULL, 0, 1000);
 | |
| 		if (i < 0) {
 | |
| 			fprintf(stderr, "usb_control_msg failed %d\n", i);
 | |
|                         break;
 | |
| 		}
 | |
| 		dwBytes = 0;
 | |
| 		starttimer();
 | |
| 		while (MemCmd.dwLength > 0) {
 | |
| 			dwChunk = MIN(dwBlockSize, MemCmd.dwLength);
 | |
| 			i = usb_bulk_read(hdl, 0x82, (char *)abData, dwChunk, 2000);
 | |
| 			if (i < 1) {
 | |
| 				fprintf(stderr, "usb_bulk_read failed %d\n", i);
 | |
| 				break;
 | |
| 			}
 | |
| 			MemCmd.dwLength -= dwChunk;
 | |
| 			dwBytes += dwBlockSize;
 | |
| 			if (stoptimer() > MAX_TIME) {
 | |
| 				break;
 | |
| 			}
 | |
| 		}
 | |
|                 if (i<0)
 | |
|                     break;
 | |
| 		iTimer = stoptimer();
 | |
|                 if (iTimer)
 | |
|                     fprintf(stderr, " %7d bytes in %d ms = %d kB/s\n", dwBytes, iTimer, dwBytes / iTimer);
 | |
| 		// stdout
 | |
| 		printf("%d,%d,%d\n", dwBlockSize, dwBytes, iTimer);
 | |
| #endif
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	usb_release_interface(hdl, 0);
 | |
| 	usb_close(hdl);
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 |