if (eeprom == 0)
ftdi_error_return(-2, "Can't malloc struct ftdi_eeprom");
+ memset(eeprom, 0, sizeof(struct ftdi_eeprom));
ftdi->eeprom = eeprom;
/* All fine. Now allocate the readbuffer */
\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");
*/
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;
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;
// 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[0x18] = eeprom->chip;
break;
+ case TYPE_4232H:
+ fprintf(stderr,"FIXME: Build FT4232H specific EEPROM settings\n");
}
// calculate checksum
// 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;;
Chip is 93x46 if magic is read at word position 0x00, as wraparound happens around 0x40
Chip is 93x56 if magic is read at word position 0x40, as wraparound happens around 0x80
Chip is 93x66 if magic is only read at word position 0xc0*/
- if( ftdi_write_eeprom_location(ftdi, 0xc0, MAGIC))
+ if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
+ SIO_WRITE_EEPROM_REQUEST, MAGIC, 0xc0,
+ NULL, 0, ftdi->usb_write_timeout) != 0)
ftdi_error_return(-3, "Writing magic failed");
if (ftdi_read_eeprom_location( ftdi, 0x00, &eeprom_value))
ftdi_error_return(-4, "Reading failed failed");