f0111cc871b6ed2ed1e336e37f0d94de344427ec
[pub/pl2303-ft232-gpio.git] / pl2303.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 <usb.h>
13 #include <getopt.h>
14
15
16 #define _GNU_SOURCE
17 #include <getopt.h>
18
19
20 #define I_VENDOR_NUM 0x67b
21 #define I_PRODUCT_NUM 0x2303
22
23
24 #define VENDOR_READ_REQUEST_TYPE 0xc0
25 #define VENDOR_READ_REQUEST 0x01
26
27 #define VENDOR_WRITE_REQUEST_TYPE 0x40
28 #define VENDOR_WRITE_REQUEST 0x01
29
30
31
32 /* Get current GPIO register from PL2303 */
33 char gpio_read_reg(usb_dev_handle *h)
34 {
35 char buf;
36 int bytes = usb_control_msg(
37 h, // handle obtained with usb_open()
38 VENDOR_READ_REQUEST_TYPE, // bRequestType
39 VENDOR_READ_REQUEST, // bRequest
40 0x0081, // wValue
41 0, // wIndex
42 &buf, // pointer to destination buffer
43 1, // wLength
44 100
45 );
46 handle_error(bytes);
47 return buf;
48 }
49
50 void gpio_write_reg(usb_dev_handle *h, unsigned char reg)
51 {
52 int bytes = usb_control_msg(
53 h, // handle obtained with usb_open()
54 VENDOR_WRITE_REQUEST_TYPE, // bRequestType
55 VENDOR_WRITE_REQUEST, // bRequest
56 1, // wValue
57 reg, // wIndex
58 0, // pointer to destination buffer
59 0, // wLength
60 6000
61 );
62 handle_error(bytes);
63
64 }
65
66 int gpio_dir_shift(int gpio) {
67 if (gpio == 0)
68 return 4;
69 if (gpio == 1)
70 return 5;
71 return 4; /* default to 0 */
72 }
73
74 int gpio_val_shift(int gpio) {
75 if (gpio == 0)
76 return 6;
77 if (gpio == 1)
78 return 7;
79 return 6; /* default to 0 */
80 }
81
82
83 void gpio_out(usb_dev_handle *h, int gpio, int value)
84 {
85 int shift_dir = gpio_dir_shift(gpio);
86 int shift_val = gpio_val_shift(gpio);
87 unsigned char reg = gpio_read_reg(h);
88 reg |= (1 << shift_dir);
89 reg &= ~(1 << shift_val);
90 reg |= (value << shift_val);
91 gpio_write_reg(h, reg);
92 }
93
94 void gpio_in(usb_dev_handle *h, int gpio, int pullup)
95 {
96 int shift_dir = gpio_dir_shift(gpio);
97 int shift_val = gpio_val_shift(gpio);
98
99 unsigned char reg = gpio_read_reg(h);
100 reg &= ~(1 << shift_dir);
101 reg &= ~(1 << shift_val);
102 reg |= (pullup << shift_val);
103 gpio_write_reg(h, reg);
104 }
105
106 int gpio_read(usb_dev_handle *h, int gpio)
107 {
108 unsigned char r = gpio_read_reg(h);
109 int shift = gpio_val_shift(gpio);
110 return (r & (1<<shift));
111 }
112
113 extern usb_dev_handle *nc_usb_open(int vendor, int product, char *vendor_name, char *product_name, char *serial);
114 void check_handle(usb_dev_handle **h, const char* manuf, const char* product, const char* serial)
115 {
116 if (*h)
117 return;
118
119 *h = nc_usb_open(I_VENDOR_NUM, I_PRODUCT_NUM, manuf, product, serial);
120 if (!(*h)) {
121 fprintf(stderr, "No PL2303 USB device %04x:%04x found ;(\n", I_VENDOR_NUM, I_PRODUCT_NUM);
122 exit(1);
123 }
124 }