First support PL2303-HXD GPIO 2 & 3 master
authorPeter Henn <Peter.Henn@web.de>
Mon, 23 Apr 2018 22:58:44 +0000 (22:58 +0000)
committerPeter Henn <Peter.Henn@web.de>
Tue, 24 Apr 2018 00:01:58 +0000 (00:01 +0000)
- extend pl2303 to support GPIO 2 & 3
- adjust TODO file

TODO
pl2303.c

diff --git a/TODO b/TODO
index cf3e410..b1a8717 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
 TODO:
 TODO:
-- add support for GPIO2 and GPIO3 of PL2303, see also
-  https://patchwork.kernel.org/patch/4815351/
+- add GPIO number range check, depending on device
 - add debug code for testing FT232R, especially reading GPIO configuration
 - test mixed input and output with FT232R and PL2303
 - ...
 - add debug code for testing FT232R, especially reading GPIO configuration
 - test mixed input and output with FT232R and PL2303
 - ...
index fb17c19..d1ddcc6 100644 (file)
--- a/pl2303.c
+++ b/pl2303.c
 #define VENDOR_WRITE_REQUEST_TYPE      0x40
 #define VENDOR_WRITE_REQUEST           0x01
 
 #define VENDOR_WRITE_REQUEST_TYPE      0x40
 #define VENDOR_WRITE_REQUEST           0x01
 
+#define GPIO_01_RD_CTRL                0x0081
+#define GPIO_01_WR_CTRL                0x0001
+#define GPIO_23_DIR_RD_CTRL    0x8c8c
+#define GPIO_23_DIR_WR_CTRL    0x0c0c
+#define GPIO_23_VAL_RD_CTRL    0x8d8d
+#define GPIO_23_VAL_WR_CTRL    0x0d0d
 
 int get_device_vid()
 {
 
 int get_device_vid()
 {
@@ -39,83 +45,109 @@ int get_device_pid()
 }
 
 /* Get current GPIO register from PL2303 */
 }
 
 /* Get current GPIO register from PL2303 */
-char gpio_read_reg(libusb_device_handle *h)
+char gpio_read_reg(libusb_device_handle *h, unsigned short ctrl)
 {
        char buf;
        int bytes = libusb_control_transfer(
                h,             // handle obtained with usb_open()
                VENDOR_READ_REQUEST_TYPE, // bRequestType
                VENDOR_READ_REQUEST,      // bRequest
 {
        char buf;
        int bytes = libusb_control_transfer(
                h,             // handle obtained with usb_open()
                VENDOR_READ_REQUEST_TYPE, // bRequestType
                VENDOR_READ_REQUEST,      // bRequest
-               0x0081,              // wValue
-               0,              // wIndex
-               &buf,             // pointer to destination buffer
-               1,  // wLength
+               ctrl,          // wValue
+               0,             // wIndex
+               &buf,          // pointer to destination buffer
+               1,             // wLength
                1000
                );
        handle_error(bytes);
        return buf;
 }
 
                1000
                );
        handle_error(bytes);
        return buf;
 }
 
-void gpio_write_reg(libusb_device_handle *h, unsigned char reg)
+void gpio_write_reg(libusb_device_handle *h, unsigned short ctrl, unsigned char reg)
 {
        int bytes = libusb_control_transfer(
                h,             // handle obtained with usb_open()
                VENDOR_WRITE_REQUEST_TYPE, // bRequestType
                VENDOR_WRITE_REQUEST,      // bRequest
 {
        int bytes = libusb_control_transfer(
                h,             // handle obtained with usb_open()
                VENDOR_WRITE_REQUEST_TYPE, // bRequestType
                VENDOR_WRITE_REQUEST,      // bRequest
-               1,              // wValue
-               reg,              // wIndex
+               ctrl,          // wValue
+               reg,           // wIndex
                0,             // pointer to destination buffer
                0,             // pointer to destination buffer
-               0,  // wLength
+               0,             // wLength
                1000
                );
        handle_error(bytes);
                1000
                );
        handle_error(bytes);
-       
 }
 
 }
 
-int gpio_dir_shift(int gpio) {
-       if (gpio == 0) 
-               return 4;
-       if (gpio == 1) 
-               return 5;
-       return 4; /* default to 0 */
+int gpio_dir_mask(int gpio) {
+       switch (gpio) {
+               case 0: return 0x10;
+               case 1: return 0x20;
+               case 2: return 0x03;
+               case 3: return 0x0c;
+       }
+       return 0x10; /* default to gpio 0 */
 }
 
 int gpio_val_shift(int gpio) {
 }
 
 int gpio_val_shift(int gpio) {
-       if (gpio == 0) 
-               return 6;
-       if (gpio == 1) 
-               return 7;
-       return 6; /* default to 0 */
+       switch (gpio) {
+               case 0: return 6;
+               case 1: return 7;
+               case 2: return 0;
+               case 3: return 1;
+       }
+       return 6; /* default to gpio 0 */
 }
 
 
 void gpio_out(libusb_device_handle *h, int gpio, int value)
 {
 }
 
 
 void gpio_out(libusb_device_handle *h, int gpio, int value)
 {
-       int shift_dir = gpio_dir_shift(gpio);
        int shift_val = gpio_val_shift(gpio);
        int shift_val = gpio_val_shift(gpio);
-       unsigned char reg = gpio_read_reg(h);
-       reg |= (1 << shift_dir);
-       reg &= ~(1 << shift_val);
-       reg |= (value << shift_val);
-       gpio_write_reg(h, reg);
+       unsigned char reg;
+
+       if (2 > gpio) {
+               reg = gpio_read_reg(h, GPIO_01_RD_CTRL);
+               reg |= gpio_dir_mask(gpio);  /* set output direction */
+               reg &= ~(1 << shift_val);    /* reset gpio */
+               reg |= (value << shift_val); /* set gpio to value */
+               gpio_write_reg(h, GPIO_01_WR_CTRL, reg);
+       } else {
+               reg = gpio_read_reg(h, GPIO_23_VAL_RD_CTRL);
+               reg &= ~(1 << shift_val);    /* reset gpio */
+               reg |= (value << shift_val); /* set gpio to value */
+               gpio_write_reg(h, GPIO_23_VAL_WR_CTRL, reg);
+
+               reg = gpio_read_reg(h, GPIO_23_DIR_RD_CTRL);
+               reg |= gpio_dir_mask(gpio);  /* set output direction */
+               gpio_write_reg(h, GPIO_23_DIR_WR_CTRL, reg);
+       }
 }
 
 void gpio_in(libusb_device_handle *h, int gpio, int pullup)
 {
 }
 
 void gpio_in(libusb_device_handle *h, int gpio, int pullup)
 {
-       int shift_dir = gpio_dir_shift(gpio);
        int shift_val = gpio_val_shift(gpio);
        int shift_val = gpio_val_shift(gpio);
-
-       unsigned char reg = gpio_read_reg(h);
-       reg &= ~(1 << shift_dir);
-       reg &= ~(1 << shift_val);
-       reg |= (pullup << shift_val);
-       gpio_write_reg(h, reg);
+       unsigned char reg;
+
+       if (2 > gpio) {
+               reg = gpio_read_reg(h, GPIO_01_RD_CTRL);
+               reg &= ~(gpio_dir_mask(gpio));  /* set input direction */
+               reg &= ~(1 << shift_val);       /* reset gpio value */
+               reg |= (pullup << shift_val);   /* pullup gpio value */
+               gpio_write_reg(h, GPIO_01_WR_CTRL, reg);
+       } else {
+               reg = gpio_read_reg(h, GPIO_23_DIR_RD_CTRL);
+               reg &= ~(gpio_dir_mask(gpio));  /* set input direction */
+               gpio_write_reg(h, GPIO_23_DIR_WR_CTRL, reg);
+
+               reg = gpio_read_reg(h, GPIO_23_VAL_RD_CTRL);
+               reg &= ~(1 << shift_val);       /* reset gpio value */
+               reg |= (pullup << shift_val);   /* pullup gpio value */
+               gpio_write_reg(h, GPIO_23_VAL_WR_CTRL, reg);
+       }
 }
 
 int gpio_read(libusb_device_handle *h, int gpio)
 {
 }
 
 int gpio_read(libusb_device_handle *h, int gpio)
 {
-       unsigned char r = gpio_read_reg(h);
+       unsigned char r = gpio_read_reg(h, (2 > gpio) ? GPIO_01_RD_CTRL : GPIO_23_VAL_RD_CTRL);
        int shift = gpio_val_shift(gpio);
        int shift = gpio_val_shift(gpio);
-       return (r & (1<<shift));
+       return (r & (1 << shift));
 }
 
 }