\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
if (ftdi == NULL)
ftdi_error_return(-1, "No struct ftdi_context");
-
if (ftdi->eeprom == NULL)
ftdi_error_return(-2,"No struct ftdi_eeprom");
\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;
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;
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[0x00] |= DRIVER_VCP;
else
output[0x00] &= ~DRIVER_VCP;
-
+
if ( eeprom->high_current_a == HIGH_CURRENT_DRIVE)
output[0x00] |= HIGH_CURRENT_DRIVE;
else
output[0x01] |= DRIVER_VCP;
else
output[0x01] &= ~DRIVER_VCP;
-
+
if ( eeprom->high_current_b == HIGH_CURRENT_DRIVE)
output[0x01] |= HIGH_CURRENT_DRIVE;
else
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
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
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;
output[0x01] |= SUSPEND_DBUS7;
else
output[0x01] &= ~SUSPEND_DBUS7;
-
+
if (eeprom->suspend_pull_downs == 1)
output[0x0A] |= 0x4;
else
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
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;;