Add Support for FT232R
[pub/pl2303-ft232-gpio.git] / ft232r.c
diff --git a/ft232r.c b/ft232r.c
new file mode 100644 (file)
index 0000000..e8a558f
--- /dev/null
+++ b/ft232r.c
@@ -0,0 +1,114 @@
+#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 <libusb.h>
+#include <getopt.h>
+
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+
+#define I_VENDOR_NUM        0x0403
+#define I_PRODUCT_NUM       0x6001
+#define BITMODE_CBUS        0x20
+#define BITMODE_RESET       0x00
+
+#define FTDI_SIO_SET_BITMODE 11 /* Set the bitmode */
+#define FTDI_SIO_READ_PINS 12   /* Read pins in bitmode */
+
+#define FTDI_SIO_SET_BITMODE_REQUEST FTDI_SIO_SET_BITMODE
+#define FTDI_SIO_SET_BITMODE_REQUEST_TYPE 0x40
+
+#define FTDI_SIO_READ_PINS_REQUEST FTDI_SIO_READ_PINS
+#define FTDI_SIO_READ_PINS_REQUEST_TYPE 0xC0
+
+int get_device_vid()
+{
+       return I_VENDOR_NUM;
+}
+
+int get_device_pid()
+{
+       return I_PRODUCT_NUM;
+}
+
+/* Get current GPIO register from PL2303 */
+unsigned char gpio_read_reg(libusb_device_handle *h)
+{
+       unsigned char buf;
+       int bytes = libusb_control_transfer(
+               h,             // handle obtained with usb_open()
+               FTDI_SIO_READ_PINS_REQUEST_TYPE, // bRequestType
+               FTDI_SIO_READ_PINS_REQUEST,      // bRequest
+               0,              // 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 short reg)
+{
+       int bytes = libusb_control_transfer(
+               h,             // handle obtained with usb_open()
+               FTDI_SIO_SET_BITMODE_REQUEST_TYPE, //bRequestType
+               FTDI_SIO_SET_BITMODE_REQUEST, // bRequest
+               reg,              // wValue
+               0,              // wIndex
+               0,             // pointer to destination buffer
+               0,  // wLength
+               1000
+               );
+       handle_error(bytes);
+
+}
+
+void gpio_out(libusb_device_handle *h, int gpio, int value)
+{
+       unsigned char cbus_mask;
+
+       if ((gpio < 0) || (gpio > 3))
+               return;
+
+       cbus_mask = gpio_read_reg(h);
+       cbus_mask |= ((1 << gpio) << 4);
+       if (value)
+               cbus_mask |= (1 << gpio);
+       else
+               cbus_mask &= ~(1 << gpio);
+       gpio_write_reg(h, (BITMODE_CBUS << 8) | cbus_mask);
+}
+
+void gpio_in(libusb_device_handle *h, int gpio, int pullup)
+{
+       unsigned char cbus_mask;
+
+       if ((gpio < 0) || (gpio > 3))
+               return;
+
+       cbus_mask = gpio_read_reg(h);
+       cbus_mask &= ~((1 << gpio) << 4);
+       gpio_write_reg(h, (BITMODE_CBUS << 8) | cbus_mask);
+}
+
+int gpio_read(libusb_device_handle *h, int gpio)
+{
+       unsigned char r = gpio_read_reg(h);
+
+       if ((gpio < 0) || (gpio > 3))
+               return 0;
+       return (r & (1 << gpio)) ? 1 : 0;
+}
+