3 /* According to POSIX.1-2001 */
4 #include <sys/select.h>
20 #define I_VENDOR_NUM 0x67b
21 #define I_PRODUCT_NUM 0x2303
24 #define VENDOR_READ_REQUEST_TYPE 0xc0
25 #define VENDOR_READ_REQUEST 0x01
27 #define VENDOR_WRITE_REQUEST_TYPE 0x40
28 #define VENDOR_WRITE_REQUEST 0x01
31 void handle_error(int ret
)
34 perror("Failed to write to PL2303 device");
35 fprintf(stderr
, "Have you installed the correct udev rules?\n");
41 /* Get current GPIO register from PL2303 */
42 char gpio_read_reg(usb_dev_handle
*h
)
45 int bytes
= usb_control_msg(
46 h
, // handle obtained with usb_open()
47 VENDOR_READ_REQUEST_TYPE
, // bRequestType
48 VENDOR_READ_REQUEST
, // bRequest
51 &buf
, // pointer to destination buffer
59 void gpio_write_reg(usb_dev_handle
*h
, unsigned char reg
)
61 int bytes
= usb_control_msg(
62 h
, // handle obtained with usb_open()
63 VENDOR_WRITE_REQUEST_TYPE
, // bRequestType
64 VENDOR_WRITE_REQUEST
, // bRequest
67 0, // pointer to destination buffer
75 int gpio_dir_shift(int gpio
) {
80 return 4; /* default to 0 */
83 int gpio_val_shift(int gpio
) {
88 return 6; /* default to 0 */
92 void gpio_out(usb_dev_handle
*h
, int gpio
, int value
)
94 int shift_dir
= gpio_dir_shift(gpio
);
95 int shift_val
= gpio_val_shift(gpio
);
96 unsigned char reg
= gpio_read_reg(h
);
97 reg
|= (1 << shift_dir
);
98 reg
&= ~(1 << shift_val
);
99 reg
|= (value
<< shift_val
);
100 gpio_write_reg(h
, reg
);
103 void gpio_in(usb_dev_handle
*h
, int gpio
, int pullup
)
105 int shift_dir
= gpio_dir_shift(gpio
);
106 int shift_val
= gpio_val_shift(gpio
);
108 unsigned char reg
= gpio_read_reg(h
);
109 reg
&= ~(1 << shift_dir
);
110 reg
&= ~(1 << shift_val
);
111 reg
|= (pullup
<< shift_val
);
112 gpio_write_reg(h
, reg
);
115 int gpio_read(usb_dev_handle
*h
, int gpio
)
117 unsigned char r
= gpio_read_reg(h
);
118 int shift
= gpio_val_shift(gpio
);
119 return (r
& (1<<shift
));
122 static struct option long_options
[] =
124 /* These options set a flag. */
125 {"help", no_argument
, 0, 'h'},
126 {"gpio", required_argument
, 0, 'g'},
127 {"in", optional_argument
, 0, 'i'},
128 {"out", required_argument
, 0, 'o'},
129 {"sleep", required_argument
, 0, 's'},
130 {"read", no_argument
, 0, 'r'},
134 void usage(const char *self
)
136 printf("PL2303HXA userspace GPIO control tool\n"
137 "(c) Andrew 'Necromant' Andrianov 2014, License: GPLv3\n"
138 "Usage: %s [action1] [action2] ...\n"
140 "\t -g/--gpio n - select GPIO, n=0, 1\n"
141 "\t -i/--in - configure GPIO as input\n"
142 "\t -o/--out v - configure GPIO as output with value v\n"
143 "\t -r/--read v - Read current GPIO value\n\n"
144 "\t -s/--sleep v - Delay for v ms\n\n"
146 "\t%s --gpio=1 --out 1\n"
147 "\t%s --gpio=0 --out 0 --gpio=1 --in\n\n"
148 "All arguments are executed from left to right, you can add \n"
149 "delays using --sleep v option. e.g. \n"
150 "\t%s --gpio=0 --out 0 --sleep 1000 --gpio=0 --out 1\n"
151 "\n", self
, self
, self
, self
);
154 extern usb_dev_handle
*nc_usb_open(int vendor
, int product
, char *vendor_name
, char *product_name
, char *serial
);
155 void check_handle(usb_dev_handle
**h
)
160 /* TODO: Make a proper way to select different PL2303 devices. */
161 *h
= nc_usb_open(I_VENDOR_NUM
, I_PRODUCT_NUM
, NULL
, NULL
, NULL
);
163 fprintf(stderr
, "No PL2303 USB device %04x:%04x found ;(\n", I_VENDOR_NUM
, I_PRODUCT_NUM
);
167 /* We don't set config or claim interface, pl2303 kernel driver does
172 int main(int argc
, char* argv
[])
175 usb_dev_handle
*h
= NULL
;
183 int option_index
= 0;
185 c
= getopt_long (argc
, argv
, "hg:i:o:r:s:",
186 long_options
, &option_index
);
188 /* Detect the end of the options. */
216 gpio_out(h
, gpio
, v
);
221 unsigned long n
= atoi(optarg
);
228 printf("%d\n", gpio_read(h
, gpio
) ?
1 : 0);