c6c4d69aa1a90622f8e8d4127fa11005be5a4e82
[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 <libusb.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 int get_device_vid()
32 {
33 return I_VENDOR_NUM;
34 }
35
36 int get_device_pid()
37 {
38 return I_PRODUCT_NUM;
39 }
40
41 /* Get current GPIO register from PL2303 */
42 char gpio_read_reg(libusb_device_handle *h)
43 {
44 char buf;
45 int bytes = libusb_control_transfer(
46 h, // handle obtained with usb_open()
47 VENDOR_READ_REQUEST_TYPE, // bRequestType
48 VENDOR_READ_REQUEST, // bRequest
49 0x0081, // wValue
50 0, // wIndex
51 &buf, // pointer to destination buffer
52 1, // wLength
53 100
54 );
55 handle_error(bytes);
56 return buf;
57 }
58
59 void gpio_write_reg(libusb_device_handle *h, unsigned char reg)
60 {
61 int bytes = libusb_control_transfer(
62 h, // handle obtained with usb_open()
63 VENDOR_WRITE_REQUEST_TYPE, // bRequestType
64 VENDOR_WRITE_REQUEST, // bRequest
65 1, // wValue
66 reg, // wIndex
67 0, // pointer to destination buffer
68 0, // wLength
69 6000
70 );
71 handle_error(bytes);
72
73 }
74
75 int gpio_dir_shift(int gpio) {
76 if (gpio == 0)
77 return 4;
78 if (gpio == 1)
79 return 5;
80 return 4; /* default to 0 */
81 }
82
83 int gpio_val_shift(int gpio) {
84 if (gpio == 0)
85 return 6;
86 if (gpio == 1)
87 return 7;
88 return 6; /* default to 0 */
89 }
90
91
92 void gpio_out(libusb_device_handle *h, int gpio, int value)
93 {
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);
101 }
102
103 void gpio_in(libusb_device_handle *h, int gpio, int pullup)
104 {
105 int shift_dir = gpio_dir_shift(gpio);
106 int shift_val = gpio_val_shift(gpio);
107
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);
113 }
114
115 int gpio_read(libusb_device_handle *h, int gpio)
116 {
117 unsigned char r = gpio_read_reg(h);
118 int shift = gpio_val_shift(gpio);
119 return (r & (1<<shift));
120 }
121