use ftdi_usb_open_string() in baud_test example
[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)
e0aca3fa 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>
34#include <unistd.h>
35#include <ftdi.h>
36
37double get_prec_time()
38{
39 struct timeval tv;
40 double res;
41
42 gettimeofday(&tv,NULL);
43
44 res=tv.tv_sec;
45 res+=((double)tv.tv_usec/1000000);
46
47 return res;
48}
49
50int main(int argc, char **argv)
51{
52 struct ftdi_context ftdic;
53 int i, t;
f44dbec2
GE
54 char *txbuf;
55 char *rxbuf;
e0aca3fa
GE
56 double start, duration, plan;
57
58 // default values
59 int baud=9600;
60 int set_baud;
61 int datasize=100000;
c7f06bd4
GE
62
63 char default_devicedesc[] = "i:0x0403:0x6001";
64 char *devicedesc=default_devicedesc;
f44dbec2 65 int txchunksize=256;
e0aca3fa
GE
66 enum ftdi_mpsse_mode test_mode=BITMODE_BITBANG;
67
f44dbec2 68 while ((t = getopt (argc, argv, "b:d:p:m:c:")) != -1)
e0aca3fa
GE
69 {
70 switch (t)
71 {
72 case 'd':
73 datasize = atoi (optarg);
74 break;
75 case 'm':
76 switch(*optarg)
77 {
78 case 'r':
79 // serial
80 test_mode=BITMODE_RESET;
81 break;
82 case 'a':
83 // async
84 test_mode=BITMODE_BITBANG;
85 break;
86 case 's':
87 // sync
88 test_mode=BITMODE_SYNCBB;
89 break;
90 }
91 break;
92 case 'b':
93 baud = atoi (optarg);
94 break;
95 case 'p':
c7f06bd4 96 devicedesc=optarg;
e0aca3fa 97 break;
f44dbec2
GE
98 case 'c':
99 txchunksize = atoi (optarg);
100 break;
e0aca3fa
GE
101 }
102 }
103
f44dbec2
GE
104 txbuf=malloc(txchunksize);
105 rxbuf=malloc(txchunksize);
106 if (txbuf == NULL || rxbuf == NULL)
107 {
108 fprintf(stderr, "can't malloc\n");
109 return EXIT_FAILURE;
110 }
111
e0aca3fa
GE
112 if (ftdi_init(&ftdic) < 0)
113 {
114 fprintf(stderr, "ftdi_init failed\n");
115 return EXIT_FAILURE;
116 }
117
c7f06bd4 118 if (ftdi_usb_open_string(&ftdic, devicedesc) < 0)
e0aca3fa
GE
119 {
120 fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(&ftdic));
121 return EXIT_FAILURE;
122 }
123
124 set_baud=baud;
125 if (test_mode!=BITMODE_RESET)
126 {
127 // we do bitbang, so real baudrate / 16
128 set_baud=baud/16;
129 }
130
131 ftdi_set_baudrate(&ftdic,set_baud);
132 printf("real baudrate used: %d\n",(test_mode==BITMODE_RESET) ? ftdic.baudrate : ftdic.baudrate*16);
133
134 if (ftdi_set_bitmode(&ftdic, 0xFF,test_mode) < 0)
135 {
136 fprintf(stderr,"Can't set mode: %s\n",ftdi_get_error_string(&ftdic));
137 return EXIT_FAILURE;
138 }
139
140 if (test_mode==BITMODE_RESET)
141 {
142 // serial 8N1: 8 data bits, 1 startbit, 1 stopbit
143 plan=((double)(datasize*10))/baud;
144 }
145 else
146 {
147 // bitbang means 8 bits at once
148 plan=((double)datasize)/baud;
149 }
150
151 printf("this test should take %.2f seconds\n",plan);
152
153 // prepare data to send: 0 and 1 bits alternating (except for serial start/stopbit):
154 // maybe someone wants to look at this with a scope or logic analyzer
f44dbec2 155 for (i=0; i<txchunksize; i++)
e0aca3fa
GE
156 {
157 if (test_mode==BITMODE_RESET)
158 txbuf[i]=0xAA;
159 else
160 txbuf[i]=(i%2) ? 0xff : 0;
161 }
162
f44dbec2
GE
163 if (ftdi_write_data_set_chunksize(&ftdic, txchunksize) < 0 ||
164 ftdi_read_data_set_chunksize(&ftdic, txchunksize) < 0)
165 {
166 fprintf(stderr,"Can't set chunksize: %s\n",ftdi_get_error_string(&ftdic));
167 return EXIT_FAILURE;
168 }
169
e0aca3fa
GE
170 if(test_mode==BITMODE_SYNCBB)
171 {
f44dbec2
GE
172 // completely clear the receive buffer before beginning
173 while(ftdi_read_data(&ftdic, rxbuf, txchunksize)>0);
e0aca3fa 174 }
f44dbec2 175
e0aca3fa
GE
176 start=get_prec_time();
177
ac432dd8
GE
178 // don't wait for more data to arrive, take what we get and keep on sending
179 // yes, we really would like to have libusb 1.0+ with async read/write...
180 ftdic.usb_read_timeout=1;
181
e0aca3fa
GE
182 i=0;
183 while(i < datasize)
184 {
f44dbec2 185 int sendsize=txchunksize;
e0aca3fa
GE
186 if (i+sendsize > datasize)
187 sendsize=datasize-i;
188
189 if ((sendsize=ftdi_write_data(&ftdic, txbuf, sendsize)) < 0)
190 {
191 fprintf(stderr,"write failed at %d: %s\n",
192 i, ftdi_get_error_string(&ftdic));
193 return EXIT_FAILURE;
194 }
195
196 i+=sendsize;
197
198 if(test_mode==BITMODE_SYNCBB)
199 {
f44dbec2 200 // read the same amount of data as sent
39c9dbfc 201 ftdi_read_data(&ftdic, rxbuf, sendsize);
e0aca3fa
GE
202 }
203 }
204
205 duration=get_prec_time()-start;
39c9dbfc 206 printf("and took %.4f seconds, this is %.0f baud or factor %.3f\n",duration,(plan*baud)/duration,plan/duration);
e0aca3fa
GE
207
208 ftdi_usb_close(&ftdic);
209 ftdi_deinit(&ftdic);
210 exit (0);
211}