X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=blobdiff_plain;f=src%2Fftdi.c;h=e38122b8e9b18cd3383beaf10c0eb510b2b305f7;hp=5a27ac3ce3cfc0262a9a8f967bc935910375c896;hb=f6ef2983ec626387a30502e0369ef4d79cb1bdce;hpb=f2cd9fd5d8cac4ca8c94e4f5e6560b4967c87be5 diff --git a/src/ftdi.c b/src/ftdi.c index 5a27ac3..e38122b 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -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; @@ -2505,29 +2505,6 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size) if(ftdi->type == TYPE_R) eeprom_size = 0x80; eeprom = ftdi->eeprom; -#if 0 - size_check = eeprom->size; - size_check -= 28; // 28 are always in use (fixed) - - // Top half of a 256byte eeprom is used just for strings and checksum - // it seems that the FTDI chip will not read these strings from the lower half - // Each string starts with two bytes; offset and type (0x03 for string) - // the checksum needs two bytes, so without the string data that 8 bytes from the top half - if (eeprom->size>=256)size_check = 120; - size_check -= manufacturer_size*2; - size_check -= product_size*2; - size_check -= serial_size*2; - - // eeprom size exceeded? - if (size_check < 0) - ftdi_error_return(-1,"Size check failed"); -#endif - - // empty eeprom struct - memset(eeprom, 0, sizeof(struct 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); @@ -2535,31 +2512,15 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size) // 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]; @@ -2594,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;jmanufacturer[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;jproduct[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 0) { - eeprom->manufacturer[j] = buf[2*j+i+2]; - } - eeprom->manufacturer[j] = '\0'; - - // Decode product name - i = buf[0x10] & 0x7f; // offset - for (j=0;jproduct[j] = buf[2*j+i+2]; - } - eeprom->product[j] = '\0'; - - // Decode serial - i = buf[0x12] & 0x7f; // offset - for (j=0;jserial[j] = buf[2*j+i+2]; + eeprom->serial = malloc(serial_size); + if(eeprom->serial) + { + // Decode serial + i = buf[0x12]; // offset + for (j=0;jserial[j] = buf[2*j+i+2]; + } + eeprom->serial[j] = '\0'; + } } - eeprom->serial[j] = '\0'; + else eeprom->serial = NULL; // verify checksum checksum = 0xAAAA; @@ -2666,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; }