Adapt user area size calculation to official FTDI formula
[libftdi] / src / ftdi.c
index 8f9d0c9..9c0d53d 100644 (file)
@@ -2267,7 +2267,7 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer,
 
     \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
@@ -2277,10 +2277,10 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer,
 */
 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;
 
@@ -2307,31 +2307,10 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
     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);
@@ -2375,7 +2354,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
     // 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;
@@ -2424,48 +2403,48 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
         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;
@@ -2649,7 +2628,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
     output[eeprom->size-2] = checksum;
     output[eeprom->size-1] = checksum >> 8;
 
-    return size_check;
+    return user_area_size;
 }
 
 /**
@@ -2694,7 +2673,6 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
     // 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;;