fix mem leaks in examples ftdi_deinit -> ftdi_free
[libftdi] / examples / serial_test.c
1 /* serial_test.c
2
3    Read/write data via serial I/O
4
5    This program is distributed under the GPL, version 2
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #ifdef __WIN32__
12 #define sleep(x) Sleep(x)
13 #endif
14 #include <getopt.h>
15 #include <signal.h>
16 #include <ftdi.h>
17
18 static int exitRequested = 0;
19 /*
20  * sigintHandler --
21  *
22  *    SIGINT handler, so we can gracefully exit when the user hits ctrl-C.
23  */
24 static void
25 sigintHandler(int signum)
26 {
27     exitRequested = 1;
28 }
29
30 int main(int argc, char **argv)
31 {
32     struct ftdi_context *ftdi;
33     unsigned char buf[1024];
34     int f = 0, i;
35     int vid = 0x403;
36     int pid = 0;
37     int baudrate = 115200;
38     int interface = INTERFACE_ANY;
39     int do_write = 0;
40     unsigned int pattern = 0xffff;
41     int retval = EXIT_FAILURE;
42
43     while ((i = getopt(argc, argv, "i:v:p:b:w::")) != -1)
44     {
45         switch (i)
46         {
47             case 'i': // 0=ANY, 1=A, 2=B, 3=C, 4=D
48                 interface = strtoul(optarg, NULL, 0);
49                 break;
50             case 'v':
51                 vid = strtoul(optarg, NULL, 0);
52                 break;
53             case 'p':
54                 pid = strtoul(optarg, NULL, 0);
55                 break;
56             case 'b':
57                 baudrate = strtoul(optarg, NULL, 0);
58                 break;
59             case 'w':
60                 do_write = 1;
61                 if (optarg)
62                     pattern = strtoul(optarg, NULL, 0);
63                 if (pattern > 0xff)
64                 {
65                     fprintf(stderr, "Please provide a 8 bit pattern\n");
66                     exit(-1);
67                 }
68                 break;
69             default:
70                 fprintf(stderr, "usage: %s [-i interface] [-v vid] [-p pid] [-b baudrate] [-w [pattern]]\n", *argv);
71                 exit(-1);
72         }
73     }
74
75     // Init
76     if ((ftdi = ftdi_new()) == 0)
77     {
78         fprintf(stderr, "ftdi_new failed\n");
79         return EXIT_FAILURE;
80     }
81
82     if (!vid && !pid && (interface == INTERFACE_ANY))
83     {
84         ftdi_set_interface(ftdi, INTERFACE_ANY);
85         struct ftdi_device_list *devlist;
86         int res;
87         if ((res = ftdi_usb_find_all(ftdi, &devlist, 0, 0)) < 0)
88         {
89             fprintf(stderr, "No FTDI with default VID/PID found\n");
90             goto do_deinit;
91         }
92         if (res == 1)
93         {
94             f = ftdi_usb_open_dev(ftdi,  devlist[0].dev);
95             if (f<0)
96             {
97                 fprintf(stderr, "Unable to open device %d: (%s)",
98                         i, ftdi_get_error_string(ftdi));
99             }
100         }
101         ftdi_list_free(&devlist);
102         if (res > 1)
103         {
104             fprintf(stderr, "%d Devices found, please select Device with VID/PID\n", res);
105             /* TODO: List Devices*/
106             goto do_deinit;
107         }
108         if (res == 0)
109         {
110             fprintf(stderr, "No Devices found with default VID/PID\n");
111             goto do_deinit;
112         }
113     }
114     else
115     {
116         // Select interface
117         ftdi_set_interface(ftdi, interface);
118         
119         // Open device
120         f = ftdi_usb_open(ftdi, vid, pid);
121     }
122     if (f < 0)
123     {
124         fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi));
125         exit(-1);
126     }
127
128     // Set baudrate
129     f = ftdi_set_baudrate(ftdi, baudrate);
130     if (f < 0)
131     {
132         fprintf(stderr, "unable to set baudrate: %d (%s)\n", f, ftdi_get_error_string(ftdi));
133         exit(-1);
134     }
135     
136     /* Set line parameters
137      *
138      * TODO: Make these parameters settable from the command line
139      *
140      * Parameters are choosen that sending a continous stream of 0x55 
141      * should give a square wave
142      *
143      */
144     f = ftdi_set_line_property(ftdi, 8, STOP_BIT_1, NONE);
145     if (f < 0)
146     {
147         fprintf(stderr, "unable to set line parameters: %d (%s)\n", f, ftdi_get_error_string(ftdi));
148         exit(-1);
149     }
150     
151     if (do_write)
152         for(i=0; i<1024; i++)
153             buf[i] = pattern;
154
155     signal(SIGINT, sigintHandler);
156     while (!exitRequested)
157     {
158         if (do_write)
159             f = ftdi_write_data(ftdi, buf, 
160                                 (baudrate/512 >sizeof(buf))?sizeof(buf):
161                                 (baudrate/512)?baudrate/512:1);
162         else
163             f = ftdi_read_data(ftdi, buf, sizeof(buf));
164         if (f<0)
165             sleep(1);
166         else if(f> 0 && !do_write)
167         {
168             fprintf(stderr, "read %d bytes\n", f);
169             fwrite(buf, f, 1, stdout);
170             fflush(stderr);
171             fflush(stdout);
172         }
173     }
174     signal(SIGINT, SIG_DFL);
175     retval =  EXIT_SUCCESS;
176             
177     ftdi_usb_close(ftdi);
178     do_deinit:
179     ftdi_free(ftdi);
180
181     return retval;
182 }