fixed EEPROM user-area space checks for FT232R and FT245R chips in ftdi_eeprom_build()
[libftdi] / examples / baud_test.c
index b2dfc84..eb50e2f 100644 (file)
@@ -3,10 +3,17 @@
  * 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 
+ *  -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>
  *
@@ -24,6 +31,7 @@
 
 #include <sys/time.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include <ftdi.h>
 
@@ -31,7 +39,7 @@ double get_prec_time()
 {
     struct timeval tv;
     double res;
-    
+
     gettimeofday(&tv,NULL);
 
     res=tv.tv_sec;
@@ -42,20 +50,24 @@ double get_prec_time()
 
 int main(int argc, char **argv)
 {
-    struct ftdi_context ftdic;
+    struct ftdi_context *ftdi;
     int i, t;
-    char txbuf[256];
-    char rxbuf[4096];
+    unsigned char *txbuf;
+    unsigned char *rxbuf;
     double start, duration, plan;
+    int retval= 0;
 
     // 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)
         {
@@ -63,7 +75,7 @@ int main(int argc, char **argv)
                 datasize = atoi (optarg);
                 break;
             case 'm':
-                switch(*optarg)
+                switch (*optarg)
                 {
                     case 'r':
                         // serial
@@ -83,21 +95,34 @@ int main(int argc, char **argv)
                 baud = atoi (optarg);
                 break;
             case 'p':
-                sscanf(optarg,"0x%x",&product_id);
+                devicedesc=optarg;
+                break;
+            case 'c':
+                txchunksize = atoi (optarg);
                 break;
         }
     }
 
-    if (ftdi_init(&ftdic) < 0)
+    txbuf=malloc(txchunksize);
+    rxbuf=malloc(txchunksize);
+    if (txbuf == NULL || rxbuf == NULL)
     {
-        fprintf(stderr, "ftdi_init failed\n");
+        fprintf(stderr, "can't malloc\n");
         return EXIT_FAILURE;
     }
 
-    if (ftdi_usb_open(&ftdic, 0x0403, product_id) < 0)
+    if ((ftdi = ftdi_new()) == 0)
     {
-        fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(&ftdic));
-        return EXIT_FAILURE;
+        fprintf(stderr, "ftdi_new failed\n");
+        retval = EXIT_FAILURE;
+        goto done;
+    }
+
+    if (ftdi_usb_open_string(ftdi, devicedesc) < 0)
+    {
+        fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(ftdi));
+        retval = EXIT_FAILURE;
+        goto do_deinit;
     }
 
     set_baud=baud;
@@ -107,13 +132,14 @@ int main(int argc, char **argv)
         set_baud=baud/16;
     }
 
-    ftdi_set_baudrate(&ftdic,set_baud);
-    printf("real baudrate used: %d\n",(test_mode==BITMODE_RESET) ? ftdic.baudrate : ftdic.baudrate*16);
+    ftdi_set_baudrate(ftdi,set_baud);
+    printf("real baudrate used: %d\n",(test_mode==BITMODE_RESET) ? ftdi->baudrate : ftdi->baudrate*16);
 
-    if (ftdi_set_bitmode(&ftdic, 0xFF,test_mode) < 0)
+    if (ftdi_set_bitmode(ftdi, 0xFF,test_mode) < 0)
     {
-        fprintf(stderr,"Can't set mode: %s\n",ftdi_get_error_string(&ftdic));
-        return EXIT_FAILURE;
+        fprintf(stderr,"Can't set mode: %s\n",ftdi_get_error_string(ftdi));
+        retval = EXIT_FAILURE;
+        goto do_close;
     }
 
     if (test_mode==BITMODE_RESET)
@@ -131,7 +157,7 @@ int main(int argc, char **argv)
 
     // 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;
@@ -139,42 +165,60 @@ int main(int argc, char **argv)
             txbuf[i]=(i%2) ? 0xff : 0;
     }
 
-    if(test_mode==BITMODE_SYNCBB)
+    if (ftdi_write_data_set_chunksize(ftdi, txchunksize) < 0 ||
+            ftdi_read_data_set_chunksize(ftdi, txchunksize) < 0)
+    {
+        fprintf(stderr,"Can't set chunksize: %s\n",ftdi_get_error_string(ftdi));
+        retval = EXIT_FAILURE;
+        goto do_close;
+    }
+
+    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(ftdi, 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...
+    ftdi->usb_read_timeout=1;
+
     i=0;
-    while(i < datasize)
+    while (i < datasize)
     {
-        int sendsize=sizeof(txbuf);
+        int sendsize=txchunksize;
         if (i+sendsize > datasize)
             sendsize=datasize-i;
 
-        if ((sendsize=ftdi_write_data(&ftdic, txbuf, sendsize)) < 0)
+        if ((sendsize=ftdi_write_data(ftdi, txbuf, sendsize)) < 0)
         {
             fprintf(stderr,"write failed at %d: %s\n",
-                    i, ftdi_get_error_string(&ftdic));
-            return EXIT_FAILURE;
+                    i, ftdi_get_error_string(ftdi));
+            retval = EXIT_FAILURE;
+            goto do_close;
         }
 
         i+=sendsize;
 
-        if(test_mode==BITMODE_SYNCBB)
+        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(ftdi, rxbuf, sendsize);
         }
     }
 
     duration=get_prec_time()-start;
-    printf("and took %.4f seconds, this is factor %.2f\n",duration,plan/duration);
-
-    ftdi_usb_close(&ftdic);
-    ftdi_deinit(&ftdic);
-    exit (0);
+    printf("and took %.4f seconds, this is %.0f baud or factor %.3f\n",duration,(plan*baud)/duration,plan/duration);
+do_close:
+    ftdi_usb_close(ftdi);
+do_deinit:
+    ftdi_free(ftdi);
+done:
+    if(rxbuf)
+        free(rxbuf);
+    if(txbuf)
+        free(txbuf);
+    exit (retval);
 }