X-Git-Url: http://developer.intra2net.com/git/?a=blobdiff_plain;f=src%2Fftdi.c;h=5800f26cd8a50f8ee70a8b7078fe0d29e20f014a;hb=caec12943241837aa054c691f49c548bc2e87145;hp=9c0d53d349bf6b504b8049a0f72d3e51da23b82c;hpb=516ebfb1a0b4a53d358d2cbb09f0b4a6ae46a34e;p=libftdi diff --git a/src/ftdi.c b/src/ftdi.c index 9c0d53d..5800f26 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -2307,8 +2307,26 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) if (eeprom->serial != NULL) serial_size = strlen(eeprom->serial); - // eeprom size exceeded? - user_area_size = (48 - (manufacturer_size + product_size + serial_size)) * 2; + // eeprom size check + switch (ftdi->type) + { + case TYPE_AM: + case TYPE_BM: + user_area_size = 96; // base size for strings (total of 48 characters) + break; + case TYPE_2232C: + user_area_size = 90; // two extra config bytes and 4 bytes PnP stuff + break; + case TYPE_R: + user_area_size = 88; // four extra config bytes + 4 bytes PnP stuff + break; + case TYPE_2232H: // six extra config bytes + 4 bytes PnP stuff + case TYPE_4232H: + user_area_size = 86; + break; + } + user_area_size -= (manufacturer_size + product_size + serial_size) * 2; + if (user_area_size < 0) ftdi_error_return(-1,"eeprom size exceeded"); @@ -2327,7 +2345,8 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) // Addr 06: Device release number (0400h for BM features) output[0x06] = 0x00; - switch (ftdi->type) { + switch (ftdi->type) + { case TYPE_AM: output[0x07] = 0x02; break; @@ -2440,24 +2459,27 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[i & eeprom_size_mask] = eeprom->serial[j], i++; output[i & eeprom_size_mask] = 0x00, i++; } - output[i & eeprom_size_mask] = 0x02; /* as seen when written with FTD2XX */ - i++; - output[i & eeprom_size_mask] = 0x03; /* as seen when written with FTD2XX */ - i++; - output[i & eeprom_size_mask] = eeprom->is_not_pnp; /* as seen when written with FTD2XX */ - i++; + + // Legacy port name and PnP fields for FT2232 and newer chips + if (ftdi->type > TYPE_BM) + { + output[i & eeprom_size_mask] = 0x02; /* as seen when written with FTD2XX */ + i++; + output[i & eeprom_size_mask] = 0x03; /* as seen when written with FTD2XX */ + i++; + output[i & eeprom_size_mask] = eeprom->is_not_pnp; /* as seen when written with FTD2XX */ + i++; + } output[0x13] = serial_size*2 + 2; - if(ftdi->type > TYPE_AM) /*use_serial not used in AM devices*/ + if(ftdi->type > TYPE_AM) /* use_serial not used in AM devices */ { if (eeprom->use_serial == USE_SERIAL_NUM ) output[0x0A] |= USE_SERIAL_NUM; else output[0x0A] &= ~USE_SERIAL_NUM; } - /* Fixme: ftd2xx seems to append 0x02, 0x03 and 0x01 for PnP = 0 or 0x00 else */ - // calculate checksum /* Bytes and Bits specific to (some) types Write linear, as this allows easier fixing*/ @@ -2468,7 +2490,11 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) case TYPE_BM: output[0x0C] = eeprom->usb_version & 0xff; output[0x0D] = (eeprom->usb_version>>8) & 0xff; - output[0x14] = eeprom->chip; + if (eeprom->use_usb_version == USE_USB_VERSION_BIT) + output[0x0A] |= USE_USB_VERSION_BIT; + else + output[0x0A] &= ~USE_USB_VERSION_BIT; + break; case TYPE_2232C: @@ -2506,6 +2532,11 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x0A] |= 0x4; else output[0x0A] &= ~0x4; + if (eeprom->use_usb_version == USE_USB_VERSION_BIT) + output[0x0A] |= USE_USB_VERSION_BIT; + else + output[0x0A] &= ~USE_USB_VERSION_BIT; + output[0x0C] = eeprom->usb_version & 0xff; output[0x0D] = (eeprom->usb_version>>8) & 0xff; output[0x14] = eeprom->chip; @@ -2560,10 +2591,10 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x01] |= DRIVER_VCP; else output[0x01] &= ~DRIVER_VCP; - if(eeprom->suspend_dbus7 == SUSPEND_DBUS7) - output[0x01] |= SUSPEND_DBUS7; + if(eeprom->suspend_dbus7 == SUSPEND_DBUS7_BIT) + output[0x01] |= SUSPEND_DBUS7_BIT; else - output[0x01] &= ~SUSPEND_DBUS7; + output[0x01] &= ~SUSPEND_DBUS7_BIT; if (eeprom->suspend_pull_downs == 1) output[0x0A] |= 0x4; @@ -2674,7 +2705,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) // Bit 6: 1 if this device is self powered, 0 if bus powered // Bit 5: 1 if this device uses remote wakeup eeprom->self_powered = buf[0x08] & 0x40; - eeprom->remote_wakeup = buf[0x08] & 0x20;; + eeprom->remote_wakeup = buf[0x08] & 0x20; // Addr 09: Max power consumption: max power = value * 2 mA eeprom->max_power = buf[0x09]; @@ -2683,8 +2714,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) // Bit 7: 0 - reserved // Bit 6: 0 - reserved // Bit 5: 0 - reserved - // Bit 4: 1 - Change USB version - // Not seen on FT2232(D) + // Bit 4: 1 - Change USB version on BM and 2232C // 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 @@ -2694,11 +2724,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) eeprom->out_is_isochronous = buf[0x0A]&0x02; eeprom->suspend_pull_downs = buf[0x0A]&0x04; eeprom->use_serial = buf[0x0A] & USE_SERIAL_NUM; - 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"); - + eeprom->use_usb_version = buf[0x0A] & USE_USB_VERSION_BIT; // Addr 0C: USB version low byte when 0x0A // Addr 0D: USB version high byte when 0x0A @@ -2835,7 +2861,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) eeprom->channel_b_driver = buf[0x01] & DRIVER_VCP; if(ftdi->type == TYPE_2232H) - eeprom->suspend_dbus7 = buf[0x01] & SUSPEND_DBUS7; + eeprom->suspend_dbus7 = buf[0x01] & SUSPEND_DBUS7_BIT; eeprom->chip = buf[0x18]; eeprom->group0_drive = buf[0x0c] & DRIVE_16MA; @@ -2892,6 +2918,10 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) channel_mode[eeprom->channel_b_type], (eeprom->channel_b_driver)?" VCP":"", (eeprom->high_current_b)?" High Current IO":""); + if (((ftdi->type == TYPE_BM) || (ftdi->type == TYPE_2232C)) && + eeprom->use_usb_version == USE_USB_VERSION_BIT) + fprintf(stdout,"Use explicit USB Version %04x\n",eeprom->usb_version); + if ((ftdi->type == TYPE_2232H) || (ftdi->type == TYPE_4232H)) { fprintf(stdout,"%s has %d mA drive%s%s\n",