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);