On request, dump arguments during EEPROM decoding
[libftdi] / src / ftdi.c
index b26b655..e38122b 100644 (file)
@@ -2192,7 +2192,7 @@ void ftdi_eeprom_initdefaults(struct ftdi_context *ftdi)
 
     eeprom->self_powered = 1;
     eeprom->remote_wakeup = 1;
-    eeprom->chip_type = TYPE_BM;
+    eeprom->release = 0;
 
     eeprom->in_is_isochronous = 0;
     eeprom->out_is_isochronous = 0;
@@ -2286,9 +2286,9 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output)
     for (i = 0; i < 5; i++)
     {
         if ((eeprom->cbus_function[i] > cbus_max[i]) ||
-            (eeprom->cbus_function[i] && eeprom->chip_type != TYPE_R)) return -3;
+            (eeprom->cbus_function[i] && ftdi->type != TYPE_R)) return -3;
     }
-    if (eeprom->chip_type != TYPE_R)
+    if (ftdi->type != TYPE_R)
     {
         if (eeprom->invert) return -4;
         if (eeprom->high_current) return -5;
@@ -2316,7 +2316,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output)
     // Addr 00: High current IO
     output[0x00] = eeprom->high_current ? HIGH_CURRENT_DRIVE : 0;
     // Addr 01: IN endpoint size (for R type devices, different for FT2232)
-    if (eeprom->chip_type == TYPE_R) {
+    if (ftdi->type == TYPE_R) {
         output[0x01] = 0x40;
     }
     // Addr 02: Vendor ID
@@ -2329,7 +2329,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output)
 
     // Addr 06: Device release number (0400h for BM features)
     output[0x06] = 0x00;
-    switch (eeprom->chip_type) {
+    switch (eeprom->release) {
         case TYPE_AM:
             output[0x07] = 0x02;
             break;
@@ -2419,7 +2419,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output)
     // Dynamic content
     // In images produced by FTDI's FT_Prog for FT232R strings start at 0x18
     // Space till 0x18 should be considered as reserved.
-    if (eeprom->chip_type >= TYPE_R) {
+    if (ftdi->type >= TYPE_R) {
         i = 0x18;
     } else {
         i = 0x14;
@@ -2488,7 +2488,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output)
    FIXME: How to pass size? How to handle size field in ftdi_eeprom?
    FIXME: Strings are malloc'ed here and should be freed somewhere
 */
-int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size)
+int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, int verbose)
 {
     unsigned char i, j;
     unsigned short checksum, eeprom_checksum, value;
@@ -2506,40 +2506,21 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size)
         eeprom_size = 0x80;
     eeprom = ftdi->eeprom;
 
-    // Addr 00: High current IO
-    eeprom->high_current = (buf[0x02] & HIGH_CURRENT_DRIVE);
-
     // Addr 02: Vendor ID
     eeprom->vendor_id = buf[0x02] + (buf[0x03] << 8);
 
     // Addr 04: Product ID
     eeprom->product_id = buf[0x04] + (buf[0x05] << 8);
 
-    value = buf[0x06] + (buf[0x07]<<8);
-    switch (value)
-    {
-        case 0x0600:
-            eeprom->chip_type = TYPE_R;
-            break;
-        case 0x0400:
-            eeprom->chip_type = TYPE_BM;
-            break;
-        case 0x0200:
-            eeprom->chip_type = TYPE_AM;
-            break;
-        default: // Unknown device
-            eeprom->chip_type = 0;
-            break;
-    }
+    eeprom->release = buf[0x06] + (buf[0x07]<<8);
 
     // Addr 08: Config descriptor
     // Bit 7: always 1
     // Bit 6: 1 if this device is self powered, 0 if bus powered
     // Bit 5: 1 if this device uses remote wakeup
     // Bit 4: 1 if this device is battery powered
-    j = buf[0x08];
-    if (j&0x40) eeprom->self_powered = 1;
-    if (j&0x20) eeprom->remote_wakeup = 1;
+    eeprom->self_powered = buf[0x08] & 0x40;
+    eeprom->remote_wakeup = buf[0x08] & 0x20;;
 
     // Addr 09: Max power consumption: max power = value * 2 mA
     eeprom->max_power = buf[0x09];
@@ -2574,57 +2555,59 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size)
     // Addr 0E: Offset of the manufacturer string + 0x80, calculated later
     // Addr 0F: Length of manufacturer string
     manufacturer_size = buf[0x0F]/2;
-    if (manufacturer_size > 0) eeprom->manufacturer = malloc(manufacturer_size);
+    if (manufacturer_size > 0) 
+    {
+        eeprom->manufacturer = malloc(manufacturer_size);
+        if (eeprom->manufacturer)
+        {
+            // Decode manufacturer
+            i = buf[0x0E]; // offset
+            for (j=0;j<manufacturer_size-1;j++)
+            {
+                eeprom->manufacturer[j] = buf[2*j+i+2];
+            }
+            eeprom->manufacturer[j] = '\0';
+        }
+    }
     else eeprom->manufacturer = NULL;
 
     // Addr 10: Offset of the product string + 0x80, calculated later
     // Addr 11: Length of product string
     product_size = buf[0x11]/2;
-    if (product_size > 0) eeprom->product = malloc(product_size);
+    if (product_size > 0)
+    {
+        eeprom->product = malloc(product_size);
+        if(eeprom->product)
+        {
+            // Decode product name
+            i = buf[0x10]; // offset
+            for (j=0;j<product_size-1;j++)
+            {
+                eeprom->product[j] = buf[2*j+i+2];
+            }
+            eeprom->product[j] = '\0';
+        }
+    }
     else eeprom->product = NULL;
 
     // Addr 12: Offset of the serial string + 0x80, calculated later
     // Addr 13: Length of serial string
     serial_size = buf[0x13]/2;
-    if (serial_size > 0) eeprom->serial = malloc(serial_size);
-    else eeprom->serial = NULL;
-
-    // Addr 14: CBUS function: CBUS0, CBUS1
-    // Addr 15: CBUS function: CBUS2, CBUS3
-    // Addr 16: CBUS function: CBUS5
-    if (eeprom->chip_type == TYPE_R) {
-        eeprom->cbus_function[0] = buf[0x14] & 0x0f;
-        eeprom->cbus_function[1] = (buf[0x14] >> 4) & 0x0f;
-        eeprom->cbus_function[2] = buf[0x15] & 0x0f;
-        eeprom->cbus_function[3] = (buf[0x15] >> 4) & 0x0f;
-        eeprom->cbus_function[4] = buf[0x16] & 0x0f;
-    } else {
-        for (j=0; j<5; j++) eeprom->cbus_function[j] = 0;
-    }
-
-    // Decode manufacturer
-    i = buf[0x0E] & 0x7f; // offset
-    for (j=0;j<manufacturer_size-1;j++)
-    {
-        eeprom->manufacturer[j] = buf[2*j+i+2];
-    }
-    eeprom->manufacturer[j] = '\0';
-
-    // Decode product name
-    i = buf[0x10] & 0x7f; // offset
-    for (j=0;j<product_size-1;j++)
-    {
-        eeprom->product[j] = buf[2*j+i+2];
-    }
-    eeprom->product[j] = '\0';
-
-    // Decode serial
-    i = buf[0x12] & 0x7f; // offset
-    for (j=0;j<serial_size-1;j++)
+    if (serial_size > 0)
     {
-        eeprom->serial[j] = buf[2*j+i+2];
+        eeprom->serial = malloc(serial_size);
+        if(eeprom->serial)
+        {
+            // Decode serial
+            i = buf[0x12]; // offset
+            for (j=0;j<serial_size-1;j++)
+            {
+                eeprom->serial[j] = buf[2*j+i+2];
+            }
+            eeprom->serial[j] = '\0';
+        }
     }
-    eeprom->serial[j] = '\0';
+    else eeprom->serial = NULL;
 
     // verify checksum
     checksum = 0xAAAA;
@@ -2646,6 +2629,48 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size)
         ftdi_error_return(-1,"EEPROM checksum error");
     }
 
+    if ((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM) || (ftdi->type == TYPE_2232C))
+    {
+        eeprom->chip = buf[14];
+    }
+    if(ftdi->type == TYPE_2)
+    {
+    if(ftdi->type == TYPE_R)
+    {
+        // Addr 14: CBUS function: CBUS0, CBUS1
+        // Addr 15: CBUS function: CBUS2, CBUS3
+        // Addr 16: CBUS function: CBUS5
+        if (ftdi->type == TYPE_R) {
+            eeprom->cbus_function[0] = buf[0x14] & 0x0f;
+            eeprom->cbus_function[1] = (buf[0x14] >> 4) & 0x0f;
+            eeprom->cbus_function[2] = buf[0x15] & 0x0f;
+            eeprom->cbus_function[3] = (buf[0x15] >> 4) & 0x0f;
+            eeprom->cbus_function[4] = buf[0x16] & 0x0f;
+        } else {
+        for (j=0; j<5; j++) eeprom->cbus_function[j] = 0;
+        }
+    }
+    if(verbose)
+    {
+        fprintf(stdout, "VID:     0x%04x\n",eeprom->vendor_id);
+        fprintf(stdout, "PID:     0x%04x\n",eeprom->product_id);
+        fprintf(stdout, "Release: 0x%04x\n",eeprom->release);
+
+        if(eeprom->self_powered)
+            fprintf(stdout, "Self-Powered%s", (eeprom->remote_wakeup)?", USB Remote Wake Up\n":"\n");
+        else
+            fprintf(stdout, "Bus Powered: %3d mA%s", eeprom->max_power*2,
+                    (eeprom->remote_wakeup)?" USB Remote Wake Up\n":"\n");
+        if(eeprom->manufacturer)
+            fprintf(stdout, "Manufacturer: %s\n",eeprom->manufacturer);
+        if(eeprom->product)
+            fprintf(stdout, "Product:      %s\n",eeprom->product);
+        if(eeprom->serial)
+            fprintf(stdout, "Serial:       %s\n",eeprom->serial);
+        fprintf(stderr,     "Checksum      : %04x %04x\n", checksum);
+
+    }
+
     return 0;
 }