ftdi.c - description
-------------------
begin : Fri Apr 4 2003
- copyright : (C) 2003-2017 by Intra2net AG and the libftdi developers
+ copyright : (C) 2003-2020 by Intra2net AG and the libftdi developers
email : opensource@intra2net.com
SPDX-License-Identifier: LGPL-2.1-only
***************************************************************************/
if (libusb_get_device_descriptor(dev, &desc) < 0)
ftdi_error_return(-11, "libusb_get_device_descriptor() failed");
- if (manufacturer != NULL)
+ if (manufacturer != NULL && mnf_len > 0)
{
- if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iManufacturer, (unsigned char *)manufacturer, mnf_len) < 0)
+ if (desc.iManufacturer == 0)
+ {
+ manufacturer[0] = '\0';
+ }
+ else if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iManufacturer, (unsigned char *)manufacturer, mnf_len) < 0)
{
ftdi_usb_close_internal (ftdi);
ftdi_error_return(-7, "libusb_get_string_descriptor_ascii() failed");
}
}
- if (description != NULL)
+ if (description != NULL && desc_len > 0)
{
- if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iProduct, (unsigned char *)description, desc_len) < 0)
+ if (desc.iProduct == 0)
+ {
+ description[0] = '\0';
+ }
+ else if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iProduct, (unsigned char *)description, desc_len) < 0)
{
ftdi_usb_close_internal (ftdi);
ftdi_error_return(-8, "libusb_get_string_descriptor_ascii() failed");
}
}
- if (serial != NULL)
+ if (serial != NULL && serial_len > 0)
{
- if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iSerialNumber, (unsigned char *)serial, serial_len) < 0)
+ if (desc.iSerialNumber == 0)
+ {
+ serial[0] = '\0';
+ }
+ else if (libusb_get_string_descriptor_ascii(ftdi->usb_dev, desc.iSerialNumber, (unsigned char *)serial, serial_len) < 0)
{
ftdi_usb_close_internal (ftdi);
ftdi_error_return(-9, "libusb_get_string_descriptor_ascii() failed");
AM Type chips have only four fractional subdivisors at value[15:14]
for subdivisors 0, 0.5, 0.25, 0.125
*/
-static int ftdi_to_clkbits(int baudrate, unsigned int clk, int clk_div, unsigned long *encoded_divisor)
+static int ftdi_to_clkbits(int baudrate, int clk, int clk_div, unsigned long *encoded_divisor)
{
static const char frac_code[8] = {0, 3, 2, 4, 1, 5, 6, 7};
int best_baud = 0;
\retval -2: No struct ftdi_eeprom
\retval -3: No connected device or device not yet opened
*/
-int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer,
- char * product, char * serial)
+int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, const char * manufacturer,
+ const char * product, const char * serial)
{
struct ftdi_eeprom *eeprom;
ftdi_error_return(-3, "No connected device or device not yet opened");
eeprom->vendor_id = 0x0403;
- eeprom->use_serial = 1;
+ eeprom->use_serial = (serial != NULL);
if ((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM) ||
(ftdi->type == TYPE_R))
eeprom->product_id = 0x6001;
case TYPE_2232H:
case TYPE_4232H:
i += 2;
+ /* Fall through*/
case TYPE_R:
i += 2;
+ /* Fall through*/
case TYPE_2232C:
i += 2;
+ /* Fall through*/
case TYPE_AM:
case TYPE_BM:
i += 0x94;
}
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 & eeprom_size_mask] = serial_size*2 + 2, i++;
- output[i & eeprom_size_mask] = 0x03, i++;
- for (j = 0; j < serial_size; j++)
- {
- output[i & eeprom_size_mask] = eeprom->serial[j], i++;
- output[i & eeprom_size_mask] = 0x00, i++;
+ if (eeprom->use_serial) {
+ // Addr 12: Offset of the serial string + 0x80, calculated later
+ // Addr 13: Length of serial string
+ output[0x12] = i | 0x80; // calculate offset
+ 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 & eeprom_size_mask] = eeprom->serial[j], i++;
+ output[i & eeprom_size_mask] = 0x00, i++;
+ }
+ output[0x13] = serial_size*2 + 2;
}
// Legacy port name and PnP fields for FT2232 and newer chips
- if (ftdi->type > TYPE_BM)
+ // It doesn't appear when written with FT_Prog for FT4232H chip.
+ if (ftdi->type > TYPE_BM && ftdi->type != TYPE_4232H)
{
output[i & eeprom_size_mask] = 0x02; /* as seen when written with FTD2XX */
i++;
i++;
}
- output[0x13] = serial_size*2 + 2;
-
if (ftdi->type > TYPE_AM) /* use_serial not used in AM devices */
{
if (eeprom->use_serial)
output[0x00] = type2bit(eeprom->channel_a_type, TYPE_R);
if (eeprom->high_current)
output[0x00] |= HIGH_CURRENT_DRIVE_R;
+
+ /* Field is inverted for TYPE_R: Bit 00.3 set to 1 is D2XX, VCP is 0 */
if (eeprom->channel_a_driver)
+ output[0x00] &= ~DRIVER_VCP;
+ else
output[0x00] |= DRIVER_VCP;
+
if (eeprom->external_oscillator)
output[0x00] |= 0x02;
output[0x01] = 0x40; /* Hard coded Endpoint Size*/
set_ft232h_cbus(eeprom, output);
output[0x1e] = eeprom->chip;
- fprintf(stderr,"FIXME: Build FT232H specific EEPROM settings\n");
+ /* FIXME: Build FT232H specific EEPROM settings */
break;
case TYPE_230X:
output[0x00] = 0x80; /* Actually, leave the default value */
{
case TYPE_230X:
free_start += 2;
+ /* Fall through*/
case TYPE_232H:
free_start += 6;
+ /* Fall through*/
case TYPE_2232H:
case TYPE_4232H:
free_start += 2;
+ /* Fall through*/
case TYPE_R:
free_start += 2;
+ /* Fall through*/
case TYPE_2232C:
free_start++;
+ /* Fall through*/
case TYPE_AM:
case TYPE_BM:
free_start += 0x14;