\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
*/
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;
if (eeprom->serial != NULL)
serial_size = strlen(eeprom->serial);
- size_check = 0x80;
- 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;
- }
-
- 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);
+ user_area_size = (48 - (manufacturer_size + product_size + serial_size)) * 2;
+ if (user_area_size < 0)
+ ftdi_error_return(-1,"eeprom size exceeded");
// empty eeprom
memset (ftdi->eeprom->buf, 0, FTDI_MAX_EEPROM_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
+ // Bit 4-0: reserved - 0
j = 0x80;
if (eeprom->self_powered == 1)
j |= 0x40;
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++;
}
- output[i & k] = 0x02; /* as seen when written with FTD2XX */
+ output[i & eeprom_size_mask] = 0x02; /* as seen when written with FTD2XX */
i++;
- output[i & k] = 0x03; /* as seen when written with FTD2XX */
+ output[i & eeprom_size_mask] = 0x03; /* as seen when written with FTD2XX */
i++;
- output[i & k] = eeprom->is_not_pnp; /* as seen when written with FTD2XX */
+ output[i & eeprom_size_mask] = eeprom->is_not_pnp; /* as seen when written with FTD2XX */
i++;
output[0x13] = serial_size*2 + 2;
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;;