Fix hang on ARM platforms
[pub/pl2303-ft232-gpio.git] / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 /* According to POSIX.1-2001 */
4 #include <sys/select.h>
5 #include <string.h>
6 #include <sys/time.h>
7 #include <sys/types.h>
8 #include <unistd.h>
9 #include <termios.h>
10 #include <fcntl.h>
11 #include <signal.h>
12 #include <libusb.h>
13 #include <getopt.h>
14
15
16 #define _GNU_SOURCE
17 #include <getopt.h>
18
19 int get_device_vid();
20 int get_device_pid();
21 void check_handle(libusb_device_handle **h, int vid, int pid, const char* manuf, const char* product, const char* serial);
22 int gpio_read(libusb_device_handle *h, int gpio);
23 void gpio_in(libusb_device_handle *h, int gpio, int pullup);
24 void gpio_out(libusb_device_handle *h, int gpio, int value);
25
26
27 void handle_error(int ret)
28 {
29 if (ret<0) {
30 perror("Failed to write to PL2303 device");
31 fprintf(stderr, "Have you installed the correct udev rules?\n");
32 exit(1);
33 }
34 }
35
36 static struct option long_options[] =
37 {
38 /* These options set a flag. */
39 {"help", no_argument, 0, 'h'},
40 {"gpio", required_argument, 0, 'g'},
41 {"in", optional_argument, 0, 'i'},
42 {"out", required_argument, 0, 'o'},
43 {"sleep", required_argument, 0, 's'},
44 {"read", no_argument, 0, 'r'},
45 {"product", required_argument, 0, 'p'},
46 {"manuf", required_argument, 0, 'm'},
47 {"serial", required_argument, 0, 'n'},
48 {0, 0, 0, 0}
49 };
50
51 void usage(const char *self)
52 {
53 printf("PL2303HXA/CP2103 userspace GPIO control tool\n"
54 "(c) Andrew 'Necromant' Andrianov 2014, License: GPLv3\n"
55 "Usage: %s [action1] [action2] ...\n"
56 "Options are: \n"
57 "\t --product=blah - Use device with this 'product' string\n"
58 "\t --serial=blah - Use device with this 'serial' string\n"
59 "\t --manuf=blah - Use device with this 'manufacturer' string\n"
60 "\t -g/--gpio n - select GPIO, n=0, 1\n"
61 "\t -i/--in - configure GPIO as input\n"
62 "\t -o/--out v - configure GPIO as output with value v\n"
63 "\t -r/--read v - Read current GPIO value\n\n"
64 "\t -s/--sleep v - Delay for v ms\n\n"
65 "Examples: \n"
66 "\t%s --gpio=1 --out 1\n"
67 "\t%s --gpio=0 --out 0 --gpio=1 --in\n\n"
68 "All arguments are executed from left to right, you can add \n"
69 "delays using --sleep v option. e.g. \n"
70 "\t%s --gpio=0 --out 0 --sleep 1000 --gpio=0 --out 1\n"
71 "\n", self, self, self, self);
72 }
73
74 int main(int argc, char* argv[])
75 {
76 int c;
77 libusb_device_handle *h = NULL;
78 int gpio=0;
79 const char *product = NULL;
80 const char *manuf = NULL;
81 const char *serial = NULL;
82 if (argc == 1)
83 {
84 usage(argv[0]);
85 exit(1);
86 }
87 while(1) {
88 int option_index = 0;
89
90 c = getopt_long (argc, argv, "hg:i:o:r:s:",
91 long_options, &option_index);
92
93 /* Detect the end of the options. */
94 if (c == -1)
95 break;
96
97 switch (c)
98 {
99 case 'p':
100 product = optarg;
101 break;
102 case 'm':
103 manuf = optarg;
104 break;
105 case 'n':
106 serial = optarg;
107 break;
108 case 'h':
109 usage(argv[0]);
110 exit(1);
111 break;
112 case 'g':
113 gpio = atoi(optarg);
114 break;
115 case 'i':
116 {
117 int v=0;
118 check_handle(&h, get_device_vid(), get_device_pid(), manuf, product, serial);
119 if (optarg)
120 v = atoi(optarg);
121 gpio_in(h, gpio, v);
122 break;
123 }
124 case 'o':
125 {
126 int v=0;
127 check_handle(&h, get_device_vid(), get_device_pid(), manuf, product, serial);
128 if (optarg)
129 v = atoi(optarg);
130 gpio_out(h, gpio, v);
131 break;
132 }
133 case 's':
134 {
135 unsigned long n = atoi(optarg);
136 usleep(n*1000);
137 break;
138 }
139 case 'r':
140 {
141 check_handle(&h, get_device_vid(), get_device_pid(), manuf, product, serial);
142 printf("%d\n", gpio_read(h, gpio) ? 1 : 0);
143 break;
144 }
145
146 }
147 }
148 return 0;
149 }