Add cp2103 stuff
authorAndrew 'Necromant' Andrianov <andrew@ncrmnt.org>
Sun, 8 Feb 2015 13:51:13 +0000 (16:51 +0300)
committerAndrew 'Necromant' Andrianov <andrew@ncrmnt.org>
Sun, 8 Feb 2015 13:51:13 +0000 (16:51 +0300)
Signed-off-by: Andrew 'Necromant' Andrianov <andrew@ncrmnt.org>
10-pl2303userspace.rules
Makefile
cp2103.c [new file with mode: 0644]
main.c
pl2303.c [new file with mode: 0644]

index fe6af93..15fb336 100755 (executable)
@@ -1,5 +1,5 @@
 # PL2303 rules to allow userspace access to the dongle
 # Copy this file to /etc/udev/rules.d, reload udev rules and replug
 
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="67b", ATTR{idProduct}=="2303", GROUP="users", MODE="0666"
-
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="67b",  ATTR{idProduct}=="2303", GROUP="users", MODE="0666"
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="10c4", ATTR{idProduct}=="ea60", GROUP="users", MODE="0666"
index c7f3d1f..1fa1faa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,15 +3,19 @@ LDFLAGS = $(shell pkg-config --libs libusb-1.0)
 
 PREFIX?=/usr/local
 
-all: pl2303gpio
+all: pl2303gpio cp2103gpio
 
 OBJS=usb.c main.c
-pl2303gpio: $(OBJS)
+pl2303gpio: $(OBJS) pl2303.o
+       $(CC) $(CFLAGS) -Wall -Werror -I"../include" -o $(@) $(^) $(LDFLAGS) -lusb
+
+cp2103gpio: $(OBJS) cp2103.o
        $(CC) $(CFLAGS) -Wall -Werror -I"../include" -o $(@) $(^) $(LDFLAGS) -lusb
 
 clean:
-       -rm pl2303gpio
+       -rm pl2303gpio cp2103gpio
 
-install: pl2303gpio
+install: pl2303gpio cp2103gpio
        cp pl2303gpio $(PREFIX)/bin
-       cp 10-pl2303userspace.rules /etc/udev/rules.d
\ No newline at end of file
+       cp cp2103gpio $(PREFIX)/bin
+       cp 10-pl2303userspace.rules /etc/udev/rules.d
diff --git a/cp2103.c b/cp2103.c
new file mode 100644 (file)
index 0000000..5e4f61e
--- /dev/null
+++ b/cp2103.c
@@ -0,0 +1,141 @@
+#include <stdio.h>
+#include <stdlib.h>
+/* According to POSIX.1-2001 */
+#include <sys/select.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <usb.h>
+#include <getopt.h>
+#include <stdint.h>
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+
+#define I_VENDOR_NUM        0x10c4
+#define I_PRODUCT_NUM       0xea60
+
+
+#define VENDOR_READ_REQUEST_TYPE       0xc0
+#define VENDOR_READ_REQUEST            0x01
+
+#define VENDOR_WRITE_REQUEST_TYPE      0x40
+#define VENDOR_WRITE_REQUEST           0x01
+
+/* CP2103 GPIO */
+#define GPIO_0 0x01
+#define GPIO_1 0x02
+#define GPIO_2 0x04
+#define GPIO_3 0x08
+#define GPIO_MASK      (GPIO_0|GPIO_1|GPIO_2|GPIO_3)
+
+
+
+//GPIO_READ
+//ret = cp210x_ctlmsg(port, 0xff, 0xc0, 0x00c2, 0, gpio, 1);
+//type c0
+//value c2
+//index 0
+//buffer 1 bytes
+//length 1
+
+
+/* Get current GPIO register from PL2303 */
+char gpio_read_reg(usb_dev_handle *h)
+{
+       char buf;
+       int bytes = usb_control_msg(
+               h,             // handle obtained with usb_open()
+               0xc0, // bRequestType
+               0xff,      // bRequest
+               0xc2,              // wValue
+               0,              // wIndex
+               &buf,             // pointer to destination buffer
+               1,  // wLength
+               100
+               );
+       handle_error(bytes);
+       return buf;
+}
+
+// GPIO_WRITE
+//request 0xff
+//type 0x40
+//value 0x37e1
+//index gpioreg
+//data NULL
+//len 0
+void gpio_write_reg(usb_dev_handle *h, uint16_t reg)
+{
+       int bytes = usb_control_msg(
+               h,             // handle obtained with usb_open()
+               0x40, // bRequestType
+               0xff,      // bRequest
+               0x37e1,              // wValue
+               reg,              // wIndex
+               0,             // pointer to destination buffer
+               0,  // wLength
+               6000
+               );
+       handle_error(bytes);
+}
+
+
+void gpio_out(usb_dev_handle *h, int gnum, int value)
+{
+
+       uint16_t gpio = 0;
+       switch (gnum) { 
+       case 0: 
+               gpio |= GPIO_0;
+               if (value) 
+                       gpio |= (GPIO_0 << 8);
+               break;
+       case 1: 
+               gpio |= GPIO_1;
+               if (value) 
+                       gpio |= (GPIO_1 << 8);
+               break;
+       case 2: 
+               gpio |= GPIO_2;
+               if (value) 
+                       gpio |= (GPIO_2 << 8);
+               break;
+       case 3: 
+               gpio |= GPIO_3;
+               if (value) 
+                       gpio |= (GPIO_3 << 8);
+               break;
+       }
+       gpio_write_reg(h, gpio);
+}
+
+void gpio_in(usb_dev_handle *h, int gpio, int pullup)
+{
+       printf("FixMe: don't know how to make pins input on cp2103\n");
+}
+
+int gpio_read(usb_dev_handle *h, int gpio)
+{
+       printf("FixMe: don't know how to read pins on cp2103\n");
+}
+
+
+extern usb_dev_handle *nc_usb_open(int vendor, int product, 
+                                  const char *vendor_name, const char *product_name, const char *serial);
+void check_handle(usb_dev_handle **h, const char* manuf, const char* product, const char* serial)
+{
+       if (*h)
+               return;
+
+       *h = nc_usb_open(I_VENDOR_NUM, I_PRODUCT_NUM, manuf, product, serial);
+       if (!(*h)) {
+               fprintf(stderr, "No CP2103 USB device %04x:%04x found ;(\n", I_VENDOR_NUM, I_PRODUCT_NUM);
+               exit(1);
+       }
+}
diff --git a/main.c b/main.c
index f24e40f..8efa7cb 100644 (file)
--- a/main.c
+++ b/main.c
 #include <getopt.h>
 
 
-#define I_VENDOR_NUM        0x67b
-#define I_PRODUCT_NUM       0x2303
-
-
-#define VENDOR_READ_REQUEST_TYPE       0xc0
-#define VENDOR_READ_REQUEST            0x01
-
-#define VENDOR_WRITE_REQUEST_TYPE      0x40
-#define VENDOR_WRITE_REQUEST           0x01
+void check_handle(usb_dev_handle **h, const char* manuf, const char* product, const char* serial);
+int gpio_read(usb_dev_handle *h, int gpio);
+void gpio_in(usb_dev_handle *h, int gpio, int pullup);
+void gpio_out(usb_dev_handle *h, int gpio, int value);
 
 
 void handle_error(int ret)
@@ -37,111 +32,35 @@ void handle_error(int ret)
        }
 }
 
-
-/* Get current GPIO register from PL2303 */
-char gpio_read_reg(usb_dev_handle *h)
-{
-       char buf;
-       int bytes = usb_control_msg(
-               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
-               100
-               );
-       handle_error(bytes);
-       return buf;
-}
-
-void gpio_write_reg(usb_dev_handle *h, unsigned char reg)
-{
-       int bytes = usb_control_msg(
-               h,             // handle obtained with usb_open()
-               VENDOR_WRITE_REQUEST_TYPE, // bRequestType
-               VENDOR_WRITE_REQUEST,      // bRequest
-               1,              // wValue
-               reg,              // wIndex
-               0,             // pointer to destination buffer
-               0,  // wLength
-               6000
-               );
-       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_val_shift(int gpio) {
-       if (gpio == 0) 
-               return 6;
-       if (gpio == 1) 
-               return 7;
-       return 6; /* default to 0 */
-}
-
-
-void gpio_out(usb_dev_handle *h, int gpio, int value)
-{
-       int shift_dir = gpio_dir_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);
-}
-
-void gpio_in(usb_dev_handle *h, int gpio, int pullup)
-{
-       int shift_dir = gpio_dir_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);
-}
-
-int gpio_read(usb_dev_handle *h, int gpio)
-{
-       unsigned char r = gpio_read_reg(h);
-       int shift = gpio_val_shift(gpio);
-       return (r & (1<<shift));
-}
-
 static struct option long_options[] =
 {
        /* These options set a flag. */
-       {"help",    no_argument,       0, 'h'},
-       {"gpio",    required_argument, 0, 'g'},
-       {"in",      optional_argument, 0, 'i'},
-       {"out",     required_argument, 0, 'o'},
-       {"sleep",   required_argument, 0, 's'},
-       {"read",    no_argument,       0, 'r'},
+       {"help",    no_argument,             0, 'h'},
+       {"gpio",    required_argument,       0, 'g'},
+       {"in",      optional_argument,       0, 'i'},
+       {"out",     required_argument,       0, 'o'},
+       {"sleep",   required_argument,       0, 's'},
+       {"read",    no_argument,             0, 'r'},
+       {"product", required_argument,       0, 'p'},
+       {"manuf",   required_argument,       0, 'm'},
+       {"serial",  required_argument,       0, 'n'},
        {0, 0, 0, 0}
 };
   
 void usage(const char *self)
 {
-       printf("PL2303HXA userspace GPIO control tool\n"
+       printf("PL2303HXA/CP2103 userspace GPIO control tool\n"
               "(c) Andrew 'Necromant' Andrianov 2014, License: GPLv3\n"
               "Usage: %s [action1] [action2] ...\n"
               "Options are: \n"
-              "\t -g/--gpio  n  - select GPIO, n=0, 1\n"
-              "\t -i/--in       - configure GPIO as input\n"
-              "\t -o/--out v    - configure GPIO as output with value v\n"
-              "\t -r/--read v   - Read current GPIO value\n\n"
-              "\t -s/--sleep v  - Delay for v ms\n\n"
+              "\t --product=blah    - Use device with this 'product' string\n"
+              "\t --serial=blah     - Use device with this 'serial' string\n"
+              "\t --manuf=blah      - Use device with this 'manufacturer' string\n"
+              "\t -g/--gpio  n      - select GPIO, n=0, 1\n"
+              "\t -i/--in           - configure GPIO as input\n"
+              "\t -o/--out v        - configure GPIO as output with value v\n"
+              "\t -r/--read v       - Read current GPIO value\n\n"
+              "\t -s/--sleep v      - Delay for v ms\n\n"
               "Examples: \n"
               "\t%s --gpio=1 --out 1\n"
               "\t%s --gpio=0 --out 0 --gpio=1 --in\n\n"
@@ -151,29 +70,14 @@ void usage(const char *self)
               "\n", self, self, self, self);
 }
 
-extern usb_dev_handle *nc_usb_open(int vendor, int product, char *vendor_name, char *product_name, char *serial);
-void check_handle(usb_dev_handle **h)
-{
-       if (*h)
-               return;
-
-       /* TODO: Make a proper way to select different PL2303 devices. */
-       *h = nc_usb_open(I_VENDOR_NUM, I_PRODUCT_NUM, NULL, NULL, NULL);
-       if (!(*h)) {
-               fprintf(stderr, "No PL2303 USB device %04x:%04x found ;(\n", I_VENDOR_NUM, I_PRODUCT_NUM);
-               exit(1);
-       }
-
-       /* We don't set config or claim interface, pl2303 kernel driver does 
-        * that for us. 
-        */
-}
-
 int main(int argc, char* argv[])
 {
        char c;
        usb_dev_handle *h = NULL;
        int gpio=0; 
+       const char *product = NULL; 
+       const char *manuf = NULL;
+       const char *serial = NULL;  
        if (argc == 1) 
        {
                usage(argv[0]);
@@ -191,6 +95,15 @@ int main(int argc, char* argv[])
                
                switch (c)
                {
+               case 'p':
+                       product = optarg;
+                       break;
+               case 'm':
+                       manuf = optarg;
+                       break;
+               case 'n':
+                       serial = optarg;
+                       break;
                case 'h':
                        usage(argv[0]);
                        exit(1);
@@ -201,7 +114,7 @@ int main(int argc, char* argv[])
                case 'i':
                {
                        int v=0; 
-                       check_handle(&h);
+                       check_handle(&h, manuf, product, serial);
                        if (optarg)
                                v = atoi(optarg);
                        gpio_in(h, gpio, v); 
@@ -210,7 +123,7 @@ int main(int argc, char* argv[])
                case 'o':
                {
                        int v=0; 
-                       check_handle(&h);
+                       check_handle(&h, manuf, product, serial);
                        if (optarg)
                                v = atoi(optarg);
                        gpio_out(h, gpio, v); 
@@ -224,7 +137,7 @@ int main(int argc, char* argv[])
                }
                case 'r': 
                {
-                       check_handle(&h);
+                       check_handle(&h, manuf, product, serial);
                        printf("%d\n", gpio_read(h, gpio) ? 1 : 0); 
                        break;
                }
diff --git a/pl2303.c b/pl2303.c
new file mode 100644 (file)
index 0000000..f0111cc
--- /dev/null
+++ b/pl2303.c
@@ -0,0 +1,124 @@
+#include <stdio.h>
+#include <stdlib.h>
+/* According to POSIX.1-2001 */
+#include <sys/select.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <usb.h>
+#include <getopt.h>
+
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+
+#define I_VENDOR_NUM        0x67b
+#define I_PRODUCT_NUM       0x2303
+
+
+#define VENDOR_READ_REQUEST_TYPE       0xc0
+#define VENDOR_READ_REQUEST            0x01
+
+#define VENDOR_WRITE_REQUEST_TYPE      0x40
+#define VENDOR_WRITE_REQUEST           0x01
+
+
+
+/* Get current GPIO register from PL2303 */
+char gpio_read_reg(usb_dev_handle *h)
+{
+       char buf;
+       int bytes = usb_control_msg(
+               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
+               100
+               );
+       handle_error(bytes);
+       return buf;
+}
+
+void gpio_write_reg(usb_dev_handle *h, unsigned char reg)
+{
+       int bytes = usb_control_msg(
+               h,             // handle obtained with usb_open()
+               VENDOR_WRITE_REQUEST_TYPE, // bRequestType
+               VENDOR_WRITE_REQUEST,      // bRequest
+               1,              // wValue
+               reg,              // wIndex
+               0,             // pointer to destination buffer
+               0,  // wLength
+               6000
+               );
+       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_val_shift(int gpio) {
+       if (gpio == 0) 
+               return 6;
+       if (gpio == 1) 
+               return 7;
+       return 6; /* default to 0 */
+}
+
+
+void gpio_out(usb_dev_handle *h, int gpio, int value)
+{
+       int shift_dir = gpio_dir_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);
+}
+
+void gpio_in(usb_dev_handle *h, int gpio, int pullup)
+{
+       int shift_dir = gpio_dir_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);
+}
+
+int gpio_read(usb_dev_handle *h, int gpio)
+{
+       unsigned char r = gpio_read_reg(h);
+       int shift = gpio_val_shift(gpio);
+       return (r & (1<<shift));
+}
+
+extern usb_dev_handle *nc_usb_open(int vendor, int product, char *vendor_name, char *product_name, char *serial);
+void check_handle(usb_dev_handle **h, const char* manuf, const char* product, const char* serial)
+{
+       if (*h)
+               return;
+
+       *h = nc_usb_open(I_VENDOR_NUM, I_PRODUCT_NUM, manuf, product, serial);
+       if (!(*h)) {
+               fprintf(stderr, "No PL2303 USB device %04x:%04x found ;(\n", I_VENDOR_NUM, I_PRODUCT_NUM);
+               exit(1);
+       }
+}