eeprom->high_current = 0;
eeprom->invert = 0;
- eeprom->size = FTDI_DEFAULT_EEPROM_SIZE;
+ eeprom->size = FTDI_MAX_EEPROM_SIZE;
}
/**
unsigned char i, j;
unsigned short checksum, eeprom_checksum, value;
unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0;
- int eeprom_size = 128;
+ int eeprom_size;
struct ftdi_eeprom *eeprom;
if (ftdi == NULL)
ftdi_error_return(-1,"No context");
if (ftdi->eeprom == NULL)
ftdi_error_return(-1,"No eeprom");
-
+
+ eeprom_size = ftdi->eeprom->size;
+ if(ftdi->type == TYPE_R)
+ eeprom_size = 0x80;
eeprom = ftdi->eeprom;
-#if 0
- size_check = eeprom->size;
- size_check -= 28; // 28 are always in use (fixed)
-
- // Top half of a 256byte eeprom is used just for strings and checksum
- // it seems that the FTDI chip will not read these strings from the lower half
- // Each string starts with two bytes; offset and type (0x03 for string)
- // the checksum needs two bytes, so without the string data that 8 bytes from the top half
- if (eeprom->size>=256)size_check = 120;
- size_check -= manufacturer_size*2;
- size_check -= product_size*2;
- size_check -= serial_size*2;
-
- // eeprom size exceeded?
- if (size_check < 0)
- ftdi_error_return(-1,"Size check failed");
-#endif
-
- // empty eeprom struct
- memset(eeprom, 0, sizeof(struct ftdi_eeprom));
-
- // Addr 00: High current IO
- eeprom->high_current = (buf[0x02] & HIGH_CURRENT_DRIVE);
// Addr 02: Vendor ID
eeprom->vendor_id = buf[0x02] + (buf[0x03] << 8);
// Addr 0E: Offset of the manufacturer string + 0x80, calculated later
// Addr 0F: Length of manufacturer string
manufacturer_size = buf[0x0F]/2;
- if (manufacturer_size > 0) eeprom->manufacturer = malloc(manufacturer_size);
+ if (manufacturer_size > 0)
+ {
+ eeprom->manufacturer = malloc(manufacturer_size);
+ if (eeprom->manufacturer)
+ {
+ // Decode manufacturer
+ i = buf[0x0E]; // offset
+ for (j=0;j<manufacturer_size-1;j++)
+ {
+ eeprom->manufacturer[j] = buf[2*j+i+2];
+ }
+ eeprom->manufacturer[j] = '\0';
+ }
+ }
else eeprom->manufacturer = NULL;
// Addr 10: Offset of the product string + 0x80, calculated later
// Addr 11: Length of product string
product_size = buf[0x11]/2;
- if (product_size > 0) eeprom->product = malloc(product_size);
+ if (product_size > 0)
+ {
+ eeprom->product = malloc(product_size);
+ if(eeprom->product)
+ {
+ // Decode product name
+ i = buf[0x10]; // offset
+ for (j=0;j<product_size-1;j++)
+ {
+ eeprom->product[j] = buf[2*j+i+2];
+ }
+ eeprom->product[j] = '\0';
+ }
+ }
else eeprom->product = NULL;
// Addr 12: Offset of the serial string + 0x80, calculated later
// Addr 13: Length of serial string
serial_size = buf[0x13]/2;
- if (serial_size > 0) eeprom->serial = malloc(serial_size);
+ if (serial_size > 0)
+ {
+ eeprom->serial = malloc(serial_size);
+ if(eeprom->serial)
+ {
+ // Decode serial
+ i = buf[0x12]; // offset
+ for (j=0;j<serial_size-1;j++)
+ {
+ eeprom->serial[j] = buf[2*j+i+2];
+ }
+ eeprom->serial[j] = '\0';
+ }
+ }
else eeprom->serial = NULL;
// Addr 14: CBUS function: CBUS0, CBUS1
for (j=0; j<5; j++) eeprom->cbus_function[j] = 0;
}
- // Decode manufacturer
- i = buf[0x0E] & 0x7f; // offset
- for (j=0;j<manufacturer_size-1;j++)
- {
- eeprom->manufacturer[j] = buf[2*j+i+2];
- }
- eeprom->manufacturer[j] = '\0';
-
- // Decode product name
- i = buf[0x10] & 0x7f; // offset
- for (j=0;j<product_size-1;j++)
- {
- eeprom->product[j] = buf[2*j+i+2];
- }
- eeprom->product[j] = '\0';
-
- // Decode serial
- i = buf[0x12] & 0x7f; // offset
- for (j=0;j<serial_size-1;j++)
- {
- eeprom->serial[j] = buf[2*j+i+2];
- }
- eeprom->serial[j] = '\0';
-
// verify checksum
checksum = 0xAAAA;
if (ftdi == NULL || ftdi->usb_dev == NULL)
ftdi_error_return(-2, "USB device unavailable");
- for (i = 0; i < ftdi->eeprom->size/2; i++)
+ for (i = 0; i < FTDI_MAX_EEPROM_SIZE/2; i++)
{
if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, SIO_READ_EEPROM_REQUEST, 0, i, eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2)
ftdi_error_return(-1, "reading eeprom failed");
}
+ if (ftdi->type == TYPE_R)
+ ftdi->eeprom->size = 0xa0;
+ /* Guesses size of eeprom by comparing halves
+ - will not work with blank eeprom */
+ else if (strrchr((const char *)eeprom, 0xff) == ((const char *)eeprom +FTDI_MAX_EEPROM_SIZE -1))
+ ftdi->eeprom->size = -1;
+ else if(memcmp(eeprom,&eeprom[0x80],0x80) == 0)
+ ftdi->eeprom->size = 0x80;
+ else if(memcmp(eeprom,&eeprom[0x40],0x40) == 0)
+ ftdi->eeprom->size = 0x40;
+ else
+ ftdi->eeprom->size = 0x100;
return 0;
}
}
/**
- Guesses size of eeprom by reading eeprom and comparing halves - will not work with blank eeprom
- Call this function then do a write then call again to see if size changes, if so write again.
-
- \param ftdi pointer to ftdi_context
- \param eeprom Pointer to store eeprom into
- \param maxsize the size of the buffer to read into
-
- \retval -1: eeprom read failed
- \retval -2: USB device unavailable
- \retval >=0: size of eeprom
-*/
-int ftdi_read_eeprom_getsize(struct ftdi_context *ftdi, unsigned char *eeprom, int maxsize)
-{
- int i=0,j,minsize=32;
- int size=minsize;
-
- if (ftdi == NULL || ftdi->usb_dev == NULL)
- ftdi_error_return(-2, "USB device unavailable");
-
- do
- {
- for (j = 0; i < maxsize/2 && j<size; j++)
- {
- if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE,
- SIO_READ_EEPROM_REQUEST, 0, i,
- eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2)
- ftdi_error_return(-1, "eeprom read failed");
- i++;
- }
- size*=2;
- }
- while (size<=maxsize && memcmp(eeprom,&eeprom[size/2],size/2)!=0);
-
- return size/2;
-}
-
-/**
Write eeprom location
\param ftdi pointer to ftdi_context