libftdi, ftdi_eeprom: (tomj) changed all email addresses to opensource@intra2net.com
[libftdi] / ftdi / ftdi.c
index bd45248..d4738a9 100644 (file)
@@ -3,7 +3,7 @@
                              -------------------
     begin                : Fri Apr 4 2003
     copyright            : (C) 2003 by Intra2net AG
-    email                : info@intra2net.com
+    email                : opensource@intra2net.com
  ***************************************************************************/
 
 /***************************************************************************
@@ -102,6 +102,19 @@ int ftdi_usb_reset(struct ftdi_context *ftdi) {
     return 0;
 }
 
+int ftdi_usb_purge_buffers(struct ftdi_context *ftdi) {
+    if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 1, 0, NULL, 0, ftdi->usb_timeout) != 0) {
+        ftdi->error_str = "FTDI purge of RX buffer failed";
+        return -1;
+    }
+
+    if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 2, 0, NULL, 0, ftdi->usb_timeout) != 0) {
+        ftdi->error_str = "FTDI purge of TX buffer failed";
+        return -1;
+    }
+
+    return 0;
+}
 
 /* ftdi_usb_close return codes
     0: all fine
@@ -199,8 +212,10 @@ int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
             write_size = size-offset;
 
         ret=usb_bulk_write(ftdi->usb_dev, 2, buf+offset, write_size, ftdi->usb_timeout);
-        if (ret == -1)
+        if (ret == -1) {
+           ftdi->error_str = "bulk write failed";
             return -1;
+       }
 
         offset += write_size;
     }
@@ -210,14 +225,34 @@ int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
 
 
 int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
-    /*
-      unsigned char buf[64];
-      int read_bytes;
-
-      read_bytes = usb_bulk_read (udev, 0x81, (char *)&buf, 64, USB_TIMEOUT);
-    */
-    ftdi->error_str = "Not implemented yet";
-    return -1;
+    static unsigned char readbuf[64];
+    int ret = 1;
+    int offset = 0;
+
+    if (size != 0 && size % 64 != 0) {
+           ftdi->error_str = "Sorry, read buffer size must currently be a multiple (1x, 2x, 3x...) of 64";
+            return -2;
+    }
+
+    while (offset < size && ret > 0) {
+       ret = usb_bulk_read (ftdi->usb_dev, 0x81, readbuf, 64, ftdi->usb_timeout);
+       // Skip FTDI status bytes
+       if (ret >= 2)
+           ret-=2;
+       
+       if (ret > 0) {
+           memcpy (buf+offset, readbuf+2, ret);
+       }
+
+       if (ret == -1) {
+           ftdi->error_str = "bulk read failed";
+            return -1;
+       }
+
+        offset += ret;
+    }
+
+    return offset;
 }
 
 
@@ -267,6 +302,7 @@ int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
        return -1;
     }
 
+    usb_val = latency;
     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, 0, NULL, 0, ftdi->usb_timeout) != 0) {
        ftdi->error_str = "Unable to set latency timer";
        return -2;
@@ -277,7 +313,7 @@ int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
 
 int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency) {
     unsigned short usb_val;
-    if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x09, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
+    if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0A, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
         ftdi->error_str = "Reading latency timer failed";
         return -1;
     }
@@ -421,7 +457,7 @@ int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output) {
     output[0x13] = serial_size*2 + 2;
 
     // Dynamic content
-    output[0x14] = manufacturer_size;
+    output[0x14] = manufacturer_size*2 + 2;
     output[0x15] = 0x03;       // type: string
     
     i = 0x16, j = 0;