X-Git-Url: http://developer.intra2net.com/git/?a=blobdiff_plain;f=src%2Fftdi.c;h=7ae48cb96a794efd6102f60c6a72246426577b3d;hb=6123f7abcc98374ffcfa00bf5eb3bfe9062ada50;hp=199f3a28213487674c7878aee0fa55073d8cc120;hpb=b641e5ee64bf900594fede686f34f66c76802760;p=libftdi diff --git a/src/ftdi.c b/src/ftdi.c index 199f3a2..7ae48cb 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -2195,18 +2195,10 @@ void ftdi_eeprom_initdefaults(struct ftdi_context *ftdi) eeprom->product_id = 0x6001; else eeprom->product_id = 0x6010; - switch (ftdi->type) - { - case TYPE_2232C: - eeprom->release = 0x500; - break; - case TYPE_2232H: - eeprom->release = 0x200; - break; - default: - eeprom->release = 0; - } - eeprom->usb_version = 0x0200; + if (ftdi->type == TYPE_AM) + eeprom->usb_version = 0x0101; + else + eeprom->usb_version = 0x0200; eeprom->max_power = 50; eeprom->manufacturer = NULL; @@ -2269,7 +2261,6 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) unsigned short checksum, value; unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0; int size_check; - const int cbus_max[5] = {13, 13, 13, 13, 9}; struct ftdi_eeprom *eeprom; if (ftdi == NULL) @@ -2289,18 +2280,6 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) if (eeprom->serial != NULL) serial_size = strlen(eeprom->serial); - // highest allowed cbus value - for (i = 0; i < 5; i++) - { - if ((eeprom->cbus_function[i] > cbus_max[i]) || - (eeprom->cbus_function[i] && ftdi->type != TYPE_R)) return -3; - } - if (ftdi->type != TYPE_R) - { - if (eeprom->invert) return -4; - if (eeprom->high_current_a) return -5; - } - size_check = 0x80; switch(ftdi->type) { @@ -2346,7 +2325,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->release) { + switch (ftdi->type) { case TYPE_AM: output[0x07] = 0x02; break; @@ -2359,6 +2338,12 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) case TYPE_R: output[0x07] = 0x06; break; + case TYPE_2232H: + output[0x07] = 0x07; + break; + case TYPE_4232H: + output[0x07] = 0x08; + break; default: output[0x07] = 0x00; } @@ -2382,7 +2367,8 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) // Bit 7: 0 - reserved // Bit 6: 0 - reserved // Bit 5: 0 - reserved - // Bit 4: 1 - Change USB version + // Bit 4: 1 - Change USB version + // not seen on FT2232C) // Bit 3: 1 - Use the serial number string // Bit 2: 1 - Enable suspend pull downs for lower power // Bit 1: 1 - Out EndPoint is Isochronous @@ -2397,20 +2383,15 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) j = j | 4; if (eeprom->use_serial == 1) j = j | 8; - if (eeprom->change_usb_version == 1) - j = j | 16; output[0x0A] = j; // Addr 0B: Invert data lines output[0x0B] = eeprom->invert & 0xff; - // Addr 0C: USB version low byte when 0x0A bit 4 is set - // Addr 0D: USB version high byte when 0x0A bit 4 is set - if (eeprom->change_usb_version == 1) - { - output[0x0C] = eeprom->usb_version; - output[0x0D] = eeprom->usb_version >> 8; - } + // Addr 0C: USB version low byte + // Addr 0D: USB version high byte + output[0x0C] = eeprom->usb_version; + output[0x0D] = eeprom->usb_version >> 8; // Addr 0E: Offset of the manufacturer string + 0x80, calculated later @@ -2523,20 +2504,6 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, eeprom_size = 0x80; eeprom = ftdi->eeprom; - // Addr 00: Channel A setting - - eeprom->channel_a_type = buf[0x00] & 0x7; - eeprom->channel_a_driver = buf[0x00] & DRIVER_VCP; - eeprom->high_current_a = buf[0x00] & HIGH_CURRENT_DRIVE; - - // Addr 01: Channel B setting - - eeprom->channel_b_type = buf[0x01] & 0x7; - eeprom->channel_b_driver = buf[0x01] & DRIVER_VCP; - eeprom->high_current_b = buf[0x01] & HIGH_CURRENT_DRIVE; - - eeprom->suspend_dbus7 = buf[0x01] & SUSPEND_DBUS7; - // Addr 02: Vendor ID eeprom->vendor_id = buf[0x02] + (buf[0x03] << 8); @@ -2571,15 +2538,15 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, eeprom->out_is_isochronous = buf[0x0A]&0x02; eeprom->suspend_pull_downs = buf[0x0A]&0x04; eeprom->use_serial = buf[0x0A] & USE_SERIAL_NUM; - eeprom->change_usb_version = buf[0x0A]&0x10; + if(buf[0x0A]&0x10) + fprintf(stderr, + "EEPROM byte[0x0a] Bit 4 unexpected set. If this happened with the EEPROM\n" + "programmed by FTDI tools, please report to libftdi@developer.intra2net.com\n"); - // Addr 0C: USB version low byte when 0x0A bit 4 is set - // Addr 0D: USB version high byte when 0x0A bit 4 is set - if ((eeprom->change_usb_version == 1) || ftdi->type == TYPE_2232C) - { - eeprom->usb_version = buf[0x0C] + (buf[0x0D] << 8); - } + // Addr 0C: USB version low byte when 0x0A + // Addr 0D: USB version high byte when 0x0A + eeprom->usb_version = buf[0x0C] + (buf[0x0D] << 8); // Addr 0E: Offset of the manufacturer string + 0x80, calculated later // Addr 0F: Length of manufacturer string @@ -2658,16 +2625,33 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, ftdi_error_return(-1,"EEPROM checksum error"); } - else if ((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM)) + eeprom->channel_a_type = 0; + if ((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM)) { eeprom->chip = -1; } else if(ftdi->type == TYPE_2232C) { + eeprom->channel_a_type = buf[0x00] & 0x7; + eeprom->channel_a_driver = buf[0x00] & DRIVER_VCP; + eeprom->high_current_a = buf[0x00] & HIGH_CURRENT_DRIVE; + eeprom->channel_b_type = buf[0x01] & 0x7; + eeprom->channel_b_driver = buf[0x01] & DRIVER_VCP; + eeprom->high_current_b = buf[0x01] & HIGH_CURRENT_DRIVE; eeprom->chip = buf[0x14]; } else if(ftdi->type == TYPE_R) { + /* TYPE_R flags D2XX, not VCP as all others*/ + eeprom->channel_a_driver = (~buf[0x00]) & DRIVER_VCP; + eeprom->high_current = buf[0x00] & HIGH_CURRENT_DRIVE_R; + if( (buf[0x01]&0x40) != 0x40) + fprintf(stderr, + "TYPE_R EEPROM byte[0x01] Bit 6 unexpected Endpoint size." + " If this happened with the\n" + " EEPROM programmed by FTDI tools, please report " + "to libftdi@developer.intra2net.com\n"); + eeprom->chip = buf[0x16]; // Addr 0B: Invert data lines // Works only on FT232R, not FT245R, but no way to distinguish @@ -2683,6 +2667,14 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, } else if ((ftdi->type == TYPE_2232H) ||(ftdi->type == TYPE_4232H)) { + eeprom->high_current = buf[0x00] & HIGH_CURRENT_DRIVE_R; + eeprom->channel_a_driver = buf[0x00] & DRIVER_VCP; + eeprom->channel_b_type = buf[0x01] & 0x7; + eeprom->channel_b_driver = buf[0x01] & DRIVER_VCP; + + if(ftdi->type == TYPE_2232H) + eeprom->suspend_dbus7 = buf[0x01] & SUSPEND_DBUS7; + eeprom->chip = buf[0x18]; eeprom->group0_drive = buf[0x0c] & DRIVE_16MA; eeprom->group0_schmitt = buf[0x0c] & IS_SCHMITT; @@ -2731,12 +2723,12 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, fprintf(stdout,"Channel A has Mode %s%s%s\n", channel_mode[eeprom->channel_a_type], (eeprom->channel_a_driver)?" VCP":"", - (eeprom->high_current_a)?" High Currenr IO":""); - if (ftdi->type >= TYPE_2232C) + (eeprom->high_current_a)?" High Current IO":""); + if ((ftdi->type >= TYPE_2232C) && (ftdi->type != TYPE_R)) fprintf(stdout,"Channel B has Mode %s%s%s\n", channel_mode[eeprom->channel_b_type], (eeprom->channel_b_driver)?" VCP":"", - (eeprom->high_current_b)?" High Currenr IO":""); + (eeprom->high_current_b)?" High Current IO":""); if ((ftdi->type == TYPE_2232H) || (ftdi->type == TYPE_4232H)) { fprintf(stdout,"%s has %d mA drive%s%s\n",