#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()
{
}
/* 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
- 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;
}
-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
- 1, // wValue
- reg, // wIndex
+ ctrl, // wValue
+ reg, // wIndex
0, // pointer to destination buffer
- 0, // wLength
+ 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(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(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(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));
}