From e0aca3fac598e0ee54952d24ca32aa2507de1066 Mon Sep 17 00:00:00 2001 From: Gerd v. Egidy Date: Sun, 6 Dec 2009 14:16:00 +0100 Subject: [PATCH] add baud_test example program: compare expected and actual transfer speeds for differen baudrates --- examples/CMakeLists.txt | 2 + examples/Makefile.am | 2 + examples/baud_test.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+), 0 deletions(-) create mode 100644 examples/baud_test.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7be0978..2a8ee39 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable(bitbang_cbus bitbang_cbus.c) add_executable(bitbang_ft2232 bitbang_ft2232.c) add_executable(find_all find_all.c) add_executable(serial_read serial_read.c) +add_executable(baud_test baud_test.c) # Linkage target_link_libraries(simple ftdi) @@ -23,6 +24,7 @@ target_link_libraries(bitbang_cbus ftdi) target_link_libraries(bitbang_ft2232 ftdi) target_link_libraries(find_all ftdi) target_link_libraries(serial_read ftdi) +target_link_libraries(baud_test ftdi) # libftdi++ examples if(FTDI_BUILD_CPP) diff --git a/examples/Makefile.am b/examples/Makefile.am index aef1328..820599a 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -17,6 +17,7 @@ bin_PROGRAMS = simple \ bitbang_cbus \ find_all \ serial_read \ + baud_test \ $(examples_libftdipp) # Don't install the example files @@ -29,6 +30,7 @@ bitbang_ft2232_SOURCES = bitbang_ft2232.c bitbang_cbus_SOURCES = bitbang_cbus.c find_all_SOURCES = find_all.c serial_read_SOURCES = serial_read.c +baud_test_SOURCES = baud_test.c if HAVE_LIBFTDIPP find_all_pp_SOURCES = find_all_pp.cpp diff --git a/examples/baud_test.c b/examples/baud_test.c new file mode 100644 index 0000000..fd4959f --- /dev/null +++ b/examples/baud_test.c @@ -0,0 +1,180 @@ +/* baud_test.c + * + * test setting the baudrate and compare it with the expected runtime + * + * options: + * -p (vendor is fixed to ftdi / 0x0403) + * -d + * -b (multiplies by 16 if bitbang as written in the ftdi datasheets) + * -m r: serial a: async bitbang s:sync bitbang + * + * (C) 2009 by Gerd v. Egidy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program 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 General Public License for more details. + * + */ + +#include +#include +#include +#include + +double get_prec_time() +{ + struct timeval tv; + double res; + + gettimeofday(&tv,NULL); + + res=tv.tv_sec; + res+=((double)tv.tv_usec/1000000); + + return res; +} + +int main(int argc, char **argv) +{ + struct ftdi_context ftdic; + int i, t; + char txbuf[256]; + char rxbuf[4096]; + double start, duration, plan; + + // default values + int baud=9600; + int set_baud; + int datasize=100000; + int product_id=0x6001; + enum ftdi_mpsse_mode test_mode=BITMODE_BITBANG; + + while ((t = getopt (argc, argv, "b:d:p:m:")) != -1) + { + switch (t) + { + case 'd': + datasize = atoi (optarg); + break; + case 'm': + switch(*optarg) + { + case 'r': + // serial + test_mode=BITMODE_RESET; + break; + case 'a': + // async + test_mode=BITMODE_BITBANG; + break; + case 's': + // sync + test_mode=BITMODE_SYNCBB; + break; + } + break; + case 'b': + baud = atoi (optarg); + break; + case 'p': + sscanf(optarg,"0x%x",&product_id); + break; + } + } + + if (ftdi_init(&ftdic) < 0) + { + fprintf(stderr, "ftdi_init failed\n"); + return EXIT_FAILURE; + } + + if (ftdi_usb_open(&ftdic, 0x0403, product_id) < 0) + { + fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(&ftdic)); + return EXIT_FAILURE; + } + + set_baud=baud; + if (test_mode!=BITMODE_RESET) + { + // we do bitbang, so real baudrate / 16 + 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); + + if (ftdi_set_bitmode(&ftdic, 0xFF,test_mode) < 0) + { + fprintf(stderr,"Can't set mode: %s\n",ftdi_get_error_string(&ftdic)); + return EXIT_FAILURE; + } + + if (test_mode==BITMODE_RESET) + { + // serial 8N1: 8 data bits, 1 startbit, 1 stopbit + plan=((double)(datasize*10))/baud; + } + else + { + // bitbang means 8 bits at once + plan=((double)datasize)/baud; + } + + printf("this test should take %.2f seconds\n",plan); + + // 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 datasize) + sendsize=datasize-i; + + if ((sendsize=ftdi_write_data(&ftdic, txbuf, sendsize)) < 0) + { + fprintf(stderr,"write failed at %d: %s\n", + i, ftdi_get_error_string(&ftdic)); + return EXIT_FAILURE; + } + + i+=sendsize; + + if(test_mode==BITMODE_SYNCBB) + { + // read everything available + ftdi_read_data(&ftdic, rxbuf, sizeof(rxbuf)); + } + } + + 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); +} -- 1.7.1