#include <termios.h>
#include <fcntl.h>
#include <signal.h>
-#include <usb.h>
+#include <libusb.h>
#include <getopt.h>
#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()
+{
+ return I_VENDOR_NUM;
+}
+
+int get_device_pid()
+{
+ return I_PRODUCT_NUM;
+}
/* Get current GPIO register from PL2303 */
-char gpio_read_reg(usb_dev_handle *h)
+char gpio_read_reg(libusb_device_handle *h, unsigned short ctrl)
{
char buf;
- int bytes = usb_control_msg(
+ 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
- 100
+ ctrl, // wValue
+ 0, // wIndex
+ &buf, // pointer to destination buffer
+ 1, // wLength
+ 1000
);
handle_error(bytes);
return buf;
}
-void gpio_write_reg(usb_dev_handle *h, unsigned char reg)
+void gpio_write_reg(libusb_device_handle *h, unsigned short ctrl, unsigned char reg)
{
- int bytes = usb_control_msg(
+ 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, // wLength
- 6000
+ 0, // wLength
+ 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) {
- 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(usb_dev_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);
- 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(usb_dev_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);
-
- 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(usb_dev_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);
- return (r & (1<<shift));
+ 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);
- }
-}