\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
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;
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);
// 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;
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*/
case TYPE_BM:
output[0x0C] = eeprom->usb_version & 0xff;
output[0x0D] = (eeprom->usb_version>>8) & 0xff;
- output[0x14] = eeprom->chip;
break;
case TYPE_2232C:
output[eeprom->size-2] = checksum;
output[eeprom->size-1] = checksum >> 8;
- return size_check;
+ return user_area_size;
}
/**
// 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];