* test setting the baudrate and compare it with the expected runtime
*
* options:
- * -p <usb-product-id> (vendor is fixed to ftdi / 0x0403)
+ * -p <devicestring> defaults to "i:0x0403:0x6001" (this is the first FT232R with default id)
+ * d:<devicenode> path of bus and device-node (e.g. "003/001") within usb device tree (usually at /proc/bus/usb/)
+ * i:<vendor>:<product> first device with given vendor and product id,
+ * ids can be decimal, octal (preceded by "0") or hex (preceded by "0x")
+ * i:<vendor>:<product>:<index> as above with index being the number of the device (starting with 0)
+ * if there are more than one
+ * s:<vendor>:<product>:<serial> first device with given vendor id, product id and serial string
* -d <datasize to send in bytes>
* -b <baudrate> (divides by 16 if bitbang as taken from the ftdi datasheets)
* -m <mode to use> r: serial a: async bitbang s:sync bitbang
+ * -c <chunksize>
*
* (C) 2009 by Gerd v. Egidy <gerd.von.egidy@intra2net.com>
*
#include <sys/time.h>
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <ftdi.h>
{
struct ftdi_context ftdic;
int i, t;
- char txbuf[256];
- char rxbuf[4096];
+ char *txbuf;
+ char *rxbuf;
double start, duration, plan;
// default values
int baud=9600;
int set_baud;
int datasize=100000;
- int product_id=0x6001;
+
+ char default_devicedesc[] = "i:0x0403:0x6001";
+ char *devicedesc=default_devicedesc;
+ int txchunksize=256;
enum ftdi_mpsse_mode test_mode=BITMODE_BITBANG;
- while ((t = getopt (argc, argv, "b:d:p:m:")) != -1)
+ while ((t = getopt (argc, argv, "b:d:p:m:c:")) != -1)
{
switch (t)
{
baud = atoi (optarg);
break;
case 'p':
- sscanf(optarg,"0x%x",&product_id);
+ devicedesc=optarg;
+ break;
+ case 'c':
+ txchunksize = atoi (optarg);
break;
}
}
+ txbuf=malloc(txchunksize);
+ rxbuf=malloc(txchunksize);
+ if (txbuf == NULL || rxbuf == NULL)
+ {
+ fprintf(stderr, "can't malloc\n");
+ return EXIT_FAILURE;
+ }
+
if (ftdi_init(&ftdic) < 0)
{
fprintf(stderr, "ftdi_init failed\n");
return EXIT_FAILURE;
}
- if (ftdi_usb_open(&ftdic, 0x0403, product_id) < 0)
+ if (ftdi_usb_open_string(&ftdic, devicedesc) < 0)
{
fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(&ftdic));
return EXIT_FAILURE;
// prepare data to send: 0 and 1 bits alternating (except for serial start/stopbit):
// maybe someone wants to look at this with a scope or logic analyzer
- for (i=0; i<sizeof(txbuf); i++)
+ for (i=0; i<txchunksize; i++)
{
if (test_mode==BITMODE_RESET)
txbuf[i]=0xAA;
txbuf[i]=(i%2) ? 0xff : 0;
}
+ if (ftdi_write_data_set_chunksize(&ftdic, txchunksize) < 0 ||
+ ftdi_read_data_set_chunksize(&ftdic, txchunksize) < 0)
+ {
+ fprintf(stderr,"Can't set chunksize: %s\n",ftdi_get_error_string(&ftdic));
+ return EXIT_FAILURE;
+ }
+
if(test_mode==BITMODE_SYNCBB)
{
- // clear the receive buffer before beginning
- // will read only as much as available
- ftdi_read_data(&ftdic, rxbuf, sizeof(rxbuf));
+ // completely clear the receive buffer before beginning
+ while(ftdi_read_data(&ftdic, rxbuf, txchunksize)>0);
}
-
+
start=get_prec_time();
+ // don't wait for more data to arrive, take what we get and keep on sending
+ // yes, we really would like to have libusb 1.0+ with async read/write...
+ ftdic.usb_read_timeout=1;
+
i=0;
while(i < datasize)
{
- int sendsize=sizeof(txbuf);
+ int sendsize=txchunksize;
if (i+sendsize > datasize)
sendsize=datasize-i;
if(test_mode==BITMODE_SYNCBB)
{
- // read everything available
- ftdi_read_data(&ftdic, rxbuf, sizeof(rxbuf));
+ // read the same amount of data as sent
+ ftdi_read_data(&ftdic, rxbuf, sendsize);
}
}
duration=get_prec_time()-start;
- printf("and took %.4f seconds, this is factor %.3f\n",duration,plan/duration);
+ printf("and took %.4f seconds, this is %.0f baud or factor %.3f\n",duration,(plan*baud)/duration,plan/duration);
ftdi_usb_close(&ftdic);
ftdi_deinit(&ftdic);