X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=blobdiff_plain;f=src%2Fftdi.c;h=b61372145df7df87b4248aefd5008a64d8b1bd7e;hp=654a8ac91f3b77f8b2b5b12fbe0fce2d541418e5;hb=814710babd85edb7560418feb87b5ed003d437b2;hpb=10186c1fa4b660a1fed39b66f1fa2ad9cfe29b19 diff --git a/src/ftdi.c b/src/ftdi.c index 654a8ac..b613721 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -2184,7 +2184,7 @@ int ftdi_set_error_char(struct ftdi_context *ftdi, \param manufacturer String to use as Manufacturer \param product String to use as Product description \param serial String to use as Serial number description - + \retval 0: all fine \retval -1: No struct ftdi_context \retval -2: No struct ftdi_eeprom @@ -2196,7 +2196,6 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer, if (ftdi == NULL) ftdi_error_return(-1, "No struct ftdi_context"); - if (ftdi->eeprom == NULL) ftdi_error_return(-2,"No struct ftdi_eeprom"); @@ -2268,7 +2267,7 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer, \param ftdi pointer to ftdi_context - \retval >0: free eeprom size + \retval >=0: size of eeprom user area in bytes \retval -1: eeprom size (128 bytes) exceeded by custom strings \retval -2: Invalid eeprom pointer \retval -3: Invalid cbus function setting @@ -2278,10 +2277,10 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer, */ int ftdi_eeprom_build(struct ftdi_context *ftdi) { - unsigned char i, j, k; + unsigned char i, j, eeprom_size_mask; unsigned short checksum, value; unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0; - int size_check; + int user_area_size; struct ftdi_eeprom *eeprom; unsigned char * output; @@ -2294,7 +2293,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output = eeprom->buf; if(eeprom->chip == -1) - ftdi_error_return(-5,"No connected EEPROM or EEPROM Type unknown"); + ftdi_error_return(-5,"No connected EEPROM or EEPROM type unknown"); if ((eeprom->chip == 0x56) || (eeprom->chip == 0x66)) eeprom->size = 0x100; @@ -2308,31 +2307,28 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) if (eeprom->serial != NULL) serial_size = strlen(eeprom->serial); - size_check = 0x80; - switch(ftdi->type) + // eeprom size check + switch (ftdi->type) { - case TYPE_2232H: - case TYPE_4232H: - size_check -= 4; - case TYPE_R: - size_check -= 4; - case TYPE_2232C: - size_check -= 4; - case TYPE_AM: - case TYPE_BM: - size_check -= 0x14*2; + 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; - size_check -= manufacturer_size*2; - size_check -= product_size*2; - size_check -= serial_size*2; - - /* Space for the string type and pointer bytes */ - size_check -= -9; - - // eeprom size exceeded? - if (size_check < 0) - return (-1); + if (user_area_size < 0) + ftdi_error_return(-1,"eeprom size exceeded"); // empty eeprom memset (ftdi->eeprom->buf, 0, FTDI_MAX_EEPROM_SIZE); @@ -2349,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; @@ -2376,7 +2373,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) // 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 + // Bit 4-0: reserved - 0 j = 0x80; if (eeprom->self_powered == 1) j |= 0x40; @@ -2425,61 +2422,64 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) i += 0x94; } /* Wrap around 0x80 for 128 byte EEPROMS (Internale and 93x46) */ - k = eeprom->size -1; + eeprom_size_mask = eeprom->size -1; // Addr 0E: Offset of the manufacturer string + 0x80, calculated later // Addr 0F: Length of manufacturer string // Output manufacturer output[0x0E] = i; // calculate offset - output[i++ & k] = manufacturer_size*2 + 2; - output[i++ & k] = 0x03; // type: string + output[i & eeprom_size_mask] = manufacturer_size*2 + 2, i++; + output[i & eeprom_size_mask] = 0x03, i++; // type: string for (j = 0; j < manufacturer_size; j++) { - output[i & k] = eeprom->manufacturer[j], i++; - output[i & k] = 0x00, i++; + output[i & eeprom_size_mask] = eeprom->manufacturer[j], i++; + output[i & eeprom_size_mask] = 0x00, i++; } output[0x0F] = manufacturer_size*2 + 2; // Addr 10: Offset of the product string + 0x80, calculated later // Addr 11: Length of product string output[0x10] = i | 0x80; // calculate offset - output[i & k] = product_size*2 + 2, i++; - output[i & k] = 0x03, i++; + output[i & eeprom_size_mask] = product_size*2 + 2, i++; + output[i & eeprom_size_mask] = 0x03, i++; for (j = 0; j < product_size; j++) { - output[i & k] = eeprom->product[j], i++; - output[i & k] = 0x00, i++; + output[i & eeprom_size_mask] = eeprom->product[j], i++; + output[i & eeprom_size_mask] = 0x00, i++; } output[0x11] = product_size*2 + 2; - + // Addr 12: Offset of the serial string + 0x80, calculated later // Addr 13: Length of serial string output[0x12] = i | 0x80; // calculate offset - output[i & k] = serial_size*2 + 2, i++; - output[i & k] = 0x03, i++; + output[i & eeprom_size_mask] = serial_size*2 + 2, i++; + output[i & eeprom_size_mask] = 0x03, i++; for (j = 0; j < serial_size; j++) { - output[i & k] = eeprom->serial[j], i++; - output[i & k] = 0x00, i++; + output[i & eeprom_size_mask] = eeprom->serial[j], i++; + output[i & eeprom_size_mask] = 0x00, 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[i & k] = 0x02; /* as seen when written with FTD2XX */ - i++; - output[i & k] = 0x03; /* as seen when written with FTD2XX */ - i++; - output[i & k] = 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*/ @@ -2490,7 +2490,6 @@ 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; break; case TYPE_2232C: @@ -2499,7 +2498,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x00] |= DRIVER_VCP; else output[0x00] &= ~DRIVER_VCP; - + if ( eeprom->high_current_a == HIGH_CURRENT_DRIVE) output[0x00] |= HIGH_CURRENT_DRIVE; else @@ -2510,7 +2509,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x01] |= DRIVER_VCP; else output[0x01] &= ~DRIVER_VCP; - + if ( eeprom->high_current_b == HIGH_CURRENT_DRIVE) output[0x01] |= HIGH_CURRENT_DRIVE; else @@ -2536,7 +2535,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) if(eeprom->high_current == HIGH_CURRENT_DRIVE_R) output[0x00] |= HIGH_CURRENT_DRIVE_R; output[0x01] = 0x40; /* Hard coded Endpoint Size*/ - + if (eeprom->suspend_pull_downs == 1) output[0x0A] |= 0x4; else @@ -2544,27 +2543,27 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x0B] = eeprom->invert; output[0x0C] = eeprom->usb_version & 0xff; output[0x0D] = (eeprom->usb_version>>8) & 0xff; - + if(eeprom->cbus_function[0] > CBUS_BB) output[0x14] = CBUS_TXLED; else output[0x14] = eeprom->cbus_function[0]; - + if(eeprom->cbus_function[1] > CBUS_BB) output[0x14] |= CBUS_RXLED<<4; else output[0x14] |= eeprom->cbus_function[1]<<4; - + if(eeprom->cbus_function[2] > CBUS_BB) output[0x15] = CBUS_TXDEN; else output[0x15] = eeprom->cbus_function[2]; - + if(eeprom->cbus_function[3] > CBUS_BB) output[0x15] |= CBUS_PWREN<<4; else output[0x15] |= eeprom->cbus_function[3]<<4; - + if(eeprom->cbus_function[4] > CBUS_CLK6) output[0x16] = CBUS_SLEEP; else @@ -2576,7 +2575,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x00] |= DRIVER_VCP; else output[0x00] &= ~DRIVER_VCP; - + output[0x01] = (eeprom->channel_b_type); if ( eeprom->channel_b_driver == DRIVER_VCP) output[0x01] |= DRIVER_VCP; @@ -2586,7 +2585,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x01] |= SUSPEND_DBUS7; else output[0x01] &= ~SUSPEND_DBUS7; - + if (eeprom->suspend_pull_downs == 1) output[0x0A] |= 0x4; else @@ -2609,7 +2608,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x0c] |= IS_SCHMITT<<4; if (eeprom->group1_slew == SLOW_SLEW) output[0x0c] |= SLOW_SLEW<<4; - + if(eeprom->group2_drive > DRIVE_16MA) output[0x0d] |= DRIVE_16MA; else @@ -2650,7 +2649,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[eeprom->size-2] = checksum; output[eeprom->size-1] = checksum >> 8; - return size_check; + return user_area_size; } /** @@ -2695,9 +2694,8 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) // 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 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];