fixed EEPROM user-area space checks for FT232R and FT245R chips in ftdi_eeprom_build()
[libftdi] / examples / baud_test.c
CommitLineData
e0aca3fa
GE
1/* baud_test.c
2 *
3 * test setting the baudrate and compare it with the expected runtime
4 *
5 * options:
c7f06bd4
GE
6 * -p <devicestring> defaults to "i:0x0403:0x6001" (this is the first FT232R with default id)
7 * d:<devicenode> path of bus and device-node (e.g. "003/001") within usb device tree (usually at /proc/bus/usb/)
8 * i:<vendor>:<product> first device with given vendor and product id,
9 * ids can be decimal, octal (preceded by "0") or hex (preceded by "0x")
10 * i:<vendor>:<product>:<index> as above with index being the number of the device (starting with 0)
11 * if there are more than one
12 * s:<vendor>:<product>:<serial> first device with given vendor id, product id and serial string
e0aca3fa 13 * -d <datasize to send in bytes>
97834102 14 * -b <baudrate> (divides by 16 if bitbang as taken from the ftdi datasheets)
05c2e40a 15 * -m <mode to use> r: serial a: async bitbang s:sync bitbang
f44dbec2 16 * -c <chunksize>
e0aca3fa
GE
17 *
18 * (C) 2009 by Gerd v. Egidy <gerd.von.egidy@intra2net.com>
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 */
31
32#include <sys/time.h>
33#include <stdio.h>
579b006f 34#include <stdlib.h>
e0aca3fa
GE
35#include <unistd.h>
36#include <ftdi.h>
37
38double get_prec_time()
39{
40 struct timeval tv;
41 double res;
05c2e40a 42
e0aca3fa
GE
43 gettimeofday(&tv,NULL);
44
45 res=tv.tv_sec;
46 res+=((double)tv.tv_usec/1000000);
47
48 return res;
49}
50
51int main(int argc, char **argv)
52{
cd2ead2f 53 struct ftdi_context *ftdi;
e0aca3fa 54 int i, t;
97c6b5f6
TJ
55 unsigned char *txbuf;
56 unsigned char *rxbuf;
e0aca3fa 57 double start, duration, plan;
a9ec26b6 58 int retval= 0;
e0aca3fa
GE
59
60 // default values
61 int baud=9600;
62 int set_baud;
63 int datasize=100000;
c7f06bd4
GE
64
65 char default_devicedesc[] = "i:0x0403:0x6001";
66 char *devicedesc=default_devicedesc;
f44dbec2 67 int txchunksize=256;
e0aca3fa 68 enum ftdi_mpsse_mode test_mode=BITMODE_BITBANG;
05c2e40a 69
f44dbec2 70 while ((t = getopt (argc, argv, "b:d:p:m:c:")) != -1)
e0aca3fa
GE
71 {
72 switch (t)
73 {
74 case 'd':
75 datasize = atoi (optarg);
76 break;
77 case 'm':
05c2e40a 78 switch (*optarg)
e0aca3fa
GE
79 {
80 case 'r':
81 // serial
82 test_mode=BITMODE_RESET;
83 break;
84 case 'a':
85 // async
86 test_mode=BITMODE_BITBANG;
87 break;
88 case 's':
89 // sync
90 test_mode=BITMODE_SYNCBB;
91 break;
92 }
93 break;
94 case 'b':
95 baud = atoi (optarg);
96 break;
97 case 'p':
c7f06bd4 98 devicedesc=optarg;
e0aca3fa 99 break;
f44dbec2
GE
100 case 'c':
101 txchunksize = atoi (optarg);
102 break;
e0aca3fa
GE
103 }
104 }
105
f44dbec2
GE
106 txbuf=malloc(txchunksize);
107 rxbuf=malloc(txchunksize);
108 if (txbuf == NULL || rxbuf == NULL)
109 {
110 fprintf(stderr, "can't malloc\n");
111 return EXIT_FAILURE;
112 }
113
cd2ead2f 114 if ((ftdi = ftdi_new()) == 0)
e0aca3fa 115 {
cd2ead2f 116 fprintf(stderr, "ftdi_new failed\n");
a9ec26b6
UB
117 retval = EXIT_FAILURE;
118 goto done;
e0aca3fa
GE
119 }
120
cd2ead2f 121 if (ftdi_usb_open_string(ftdi, devicedesc) < 0)
e0aca3fa 122 {
cd2ead2f 123 fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(ftdi));
a9ec26b6
UB
124 retval = EXIT_FAILURE;
125 goto do_deinit;
e0aca3fa
GE
126 }
127
128 set_baud=baud;
129 if (test_mode!=BITMODE_RESET)
130 {
131 // we do bitbang, so real baudrate / 16
132 set_baud=baud/16;
133 }
134
cd2ead2f
UB
135 ftdi_set_baudrate(ftdi,set_baud);
136 printf("real baudrate used: %d\n",(test_mode==BITMODE_RESET) ? ftdi->baudrate : ftdi->baudrate*16);
e0aca3fa 137
cd2ead2f 138 if (ftdi_set_bitmode(ftdi, 0xFF,test_mode) < 0)
e0aca3fa 139 {
cd2ead2f 140 fprintf(stderr,"Can't set mode: %s\n",ftdi_get_error_string(ftdi));
a9ec26b6
UB
141 retval = EXIT_FAILURE;
142 goto do_close;
e0aca3fa
GE
143 }
144
145 if (test_mode==BITMODE_RESET)
146 {
147 // serial 8N1: 8 data bits, 1 startbit, 1 stopbit
148 plan=((double)(datasize*10))/baud;
149 }
150 else
151 {
152 // bitbang means 8 bits at once
153 plan=((double)datasize)/baud;
154 }
155
156 printf("this test should take %.2f seconds\n",plan);
157
158 // prepare data to send: 0 and 1 bits alternating (except for serial start/stopbit):
159 // maybe someone wants to look at this with a scope or logic analyzer
f44dbec2 160 for (i=0; i<txchunksize; i++)
e0aca3fa
GE
161 {
162 if (test_mode==BITMODE_RESET)
163 txbuf[i]=0xAA;
164 else
165 txbuf[i]=(i%2) ? 0xff : 0;
166 }
167
cd2ead2f
UB
168 if (ftdi_write_data_set_chunksize(ftdi, txchunksize) < 0 ||
169 ftdi_read_data_set_chunksize(ftdi, txchunksize) < 0)
f44dbec2 170 {
cd2ead2f 171 fprintf(stderr,"Can't set chunksize: %s\n",ftdi_get_error_string(ftdi));
a9ec26b6
UB
172 retval = EXIT_FAILURE;
173 goto do_close;
f44dbec2
GE
174 }
175
05c2e40a 176 if (test_mode==BITMODE_SYNCBB)
e0aca3fa 177 {
f44dbec2 178 // completely clear the receive buffer before beginning
cd2ead2f 179 while (ftdi_read_data(ftdi, rxbuf, txchunksize)>0);
e0aca3fa 180 }
f44dbec2 181
e0aca3fa
GE
182 start=get_prec_time();
183
ac432dd8
GE
184 // don't wait for more data to arrive, take what we get and keep on sending
185 // yes, we really would like to have libusb 1.0+ with async read/write...
cd2ead2f 186 ftdi->usb_read_timeout=1;
ac432dd8 187
e0aca3fa 188 i=0;
05c2e40a 189 while (i < datasize)
e0aca3fa 190 {
f44dbec2 191 int sendsize=txchunksize;
e0aca3fa
GE
192 if (i+sendsize > datasize)
193 sendsize=datasize-i;
194
cd2ead2f 195 if ((sendsize=ftdi_write_data(ftdi, txbuf, sendsize)) < 0)
e0aca3fa
GE
196 {
197 fprintf(stderr,"write failed at %d: %s\n",
cd2ead2f 198 i, ftdi_get_error_string(ftdi));
a9ec26b6
UB
199 retval = EXIT_FAILURE;
200 goto do_close;
e0aca3fa
GE
201 }
202
203 i+=sendsize;
204
05c2e40a 205 if (test_mode==BITMODE_SYNCBB)
e0aca3fa 206 {
f44dbec2 207 // read the same amount of data as sent
cd2ead2f 208 ftdi_read_data(ftdi, rxbuf, sendsize);
e0aca3fa
GE
209 }
210 }
211
212 duration=get_prec_time()-start;
39c9dbfc 213 printf("and took %.4f seconds, this is %.0f baud or factor %.3f\n",duration,(plan*baud)/duration,plan/duration);
a9ec26b6 214do_close:
cd2ead2f 215 ftdi_usb_close(ftdi);
a9ec26b6 216do_deinit:
cd2ead2f 217 ftdi_free(ftdi);
a9ec26b6
UB
218done:
219 if(rxbuf)
220 free(rxbuf);
221 if(txbuf)
222 free(txbuf);
025db2c2 223 exit (retval);
e0aca3fa 224}