fix documentation typo
[libftdi] / examples / baud_test.c
1 /* baud_test.c
2  *
3  * test setting the baudrate and compare it with the expected runtime
4  *
5  * options:
6  *  -p <usb-product-id> (vendor is fixed to ftdi / 0x0403)
7  *  -d <datasize to send in bytes>
8  *  -b <baudrate> (divides by 16 if bitbang as taken from the ftdi datasheets)
9  *  -m <mode to use> r: serial a: async bitbang s:sync bitbang 
10  *
11  * (C) 2009 by Gerd v. Egidy <gerd.von.egidy@intra2net.com>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  */
24
25 #include <sys/time.h>
26 #include <stdio.h>
27 #include <unistd.h>
28 #include <ftdi.h>
29
30 double get_prec_time()
31 {
32     struct timeval tv;
33     double res;
34     
35     gettimeofday(&tv,NULL);
36
37     res=tv.tv_sec;
38     res+=((double)tv.tv_usec/1000000);
39
40     return res;
41 }
42
43 int main(int argc, char **argv)
44 {
45     struct ftdi_context ftdic;
46     int i, t;
47     char txbuf[256];
48     char rxbuf[4096];
49     double start, duration, plan;
50
51     // default values
52     int baud=9600;
53     int set_baud;
54     int datasize=100000;
55     int product_id=0x6001;
56     enum ftdi_mpsse_mode test_mode=BITMODE_BITBANG;
57     
58     while ((t = getopt (argc, argv, "b:d:p:m:")) != -1)
59     {
60         switch (t)
61         {
62             case 'd':
63                 datasize = atoi (optarg);
64                 break;
65             case 'm':
66                 switch(*optarg)
67                 {
68                     case 'r':
69                         // serial
70                         test_mode=BITMODE_RESET;
71                         break;
72                     case 'a':
73                         // async
74                         test_mode=BITMODE_BITBANG;
75                         break;
76                     case 's':
77                         // sync
78                         test_mode=BITMODE_SYNCBB;
79                         break;
80                 }
81                 break;
82             case 'b':
83                 baud = atoi (optarg);
84                 break;
85             case 'p':
86                 sscanf(optarg,"0x%x",&product_id);
87                 break;
88         }
89     }
90
91     if (ftdi_init(&ftdic) < 0)
92     {
93         fprintf(stderr, "ftdi_init failed\n");
94         return EXIT_FAILURE;
95     }
96
97     if (ftdi_usb_open(&ftdic, 0x0403, product_id) < 0)
98     {
99         fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(&ftdic));
100         return EXIT_FAILURE;
101     }
102
103     set_baud=baud;
104     if (test_mode!=BITMODE_RESET)
105     {
106         // we do bitbang, so real baudrate / 16
107         set_baud=baud/16;
108     }
109
110     ftdi_set_baudrate(&ftdic,set_baud);
111     printf("real baudrate used: %d\n",(test_mode==BITMODE_RESET) ? ftdic.baudrate : ftdic.baudrate*16);
112
113     if (ftdi_set_bitmode(&ftdic, 0xFF,test_mode) < 0)
114     {
115         fprintf(stderr,"Can't set mode: %s\n",ftdi_get_error_string(&ftdic));
116         return EXIT_FAILURE;
117     }
118
119     if (test_mode==BITMODE_RESET)
120     {
121         // serial 8N1: 8 data bits, 1 startbit, 1 stopbit
122         plan=((double)(datasize*10))/baud;
123     }
124     else
125     {
126         // bitbang means 8 bits at once
127         plan=((double)datasize)/baud;
128     }
129
130     printf("this test should take %.2f seconds\n",plan);
131
132     // prepare data to send: 0 and 1 bits alternating (except for serial start/stopbit):
133     // maybe someone wants to look at this with a scope or logic analyzer
134     for (i=0; i<sizeof(txbuf); i++)
135     {
136         if (test_mode==BITMODE_RESET)
137             txbuf[i]=0xAA;
138         else
139             txbuf[i]=(i%2) ? 0xff : 0;
140     }
141
142     if(test_mode==BITMODE_SYNCBB)
143     {
144         // clear the receive buffer before beginning
145         // will read only as much as available
146         ftdi_read_data(&ftdic, rxbuf, sizeof(rxbuf));
147     }
148     
149     start=get_prec_time();
150
151     i=0;
152     while(i < datasize)
153     {
154         int sendsize=sizeof(txbuf);
155         if (i+sendsize > datasize)
156             sendsize=datasize-i;
157
158         if ((sendsize=ftdi_write_data(&ftdic, txbuf, sendsize)) < 0)
159         {
160             fprintf(stderr,"write failed at %d: %s\n",
161                     i, ftdi_get_error_string(&ftdic));
162             return EXIT_FAILURE;
163         }
164
165         i+=sendsize;
166
167         if(test_mode==BITMODE_SYNCBB)
168         {
169             // read everything available
170             ftdi_read_data(&ftdic, rxbuf, sizeof(rxbuf));
171         }
172     }
173
174     duration=get_prec_time()-start;
175     printf("and took %.4f seconds, this is factor %.2f\n",duration,plan/duration);
176
177     ftdi_usb_close(&ftdic);
178     ftdi_deinit(&ftdic);
179     exit (0);
180 }