ftdi->error_str = NULL;
- // all fine. Now allocate the readbuffer
- return ftdi_read_data_set_chunksize(ftdi, 4096);
+ /* All fine. Now allocate the readbuffer
+ Note: A readbuffer size above 64 bytes results in buggy input.
+ This seems to be a hardware limitation as noted
+ in the ftdi_sio driver */
+ return ftdi_read_data_set_chunksize(ftdi, 64);
}
if (ftdi_set_baudrate (ftdi, 9600) != 0)
return -7;
+ // Try to guess chip type
+ // Bug in the BM type chips: bcdDevice is 0x200 for serial == 0
+ if (dev->descriptor.bcdDevice == 0x400 || (dev->descriptor.bcdDevice == 0x200
+ && dev->descriptor.iSerialNumber == 0))
+ ftdi->type = TYPE_BM;
+ else if (dev->descriptor.bcdDevice == 0x200)
+ ftdi->type = TYPE_AM;
+ else if (dev->descriptor.bcdDevice == 0x500)
+ ftdi->type = TYPE_2232C;
+
return 0;
} else {
ftdi->error_str = "usb_open() failed";
ftdi_convert_baudrate returns nearest supported baud rate to that requested.
Function is only used internally
*/
-static int ftdi_convert_baudrate(int baudrate, int is_amchip,
+static int ftdi_convert_baudrate(int baudrate, struct ftdi_context *ftdi,
unsigned short *value, unsigned short *index) {
static const char am_adjust_up[8] = {0, 0, 0, 1, 0, 3, 2, 1};
static const char am_adjust_dn[8] = {0, 0, 0, 1, 0, 1, 2, 3};
divisor = 24000000 / baudrate;
- if (is_amchip) {
+ if (ftdi->type == TYPE_AM) {
// Round down to supported fraction (AM only)
divisor -= am_adjust_dn[divisor & 7];
}
if (try_divisor < 8) {
// Round up to minimum supported divisor
try_divisor = 8;
- } else if (!is_amchip && try_divisor < 12) {
+ } else if (ftdi->type != TYPE_AM && try_divisor < 12) {
// BM doesn't support divisors 9 through 11 inclusive
try_divisor = 12;
} else if (divisor < 16) {
// AM doesn't support divisors 9 through 15 inclusive
try_divisor = 16;
} else {
- if (is_amchip) {
+ if (ftdi->type == TYPE_AM) {
// Round up to supported fraction (AM only)
try_divisor += am_adjust_up[try_divisor & 7];
if (try_divisor > 0x1FFF8) {
}
// Split into "value" and "index" values
*value = (unsigned short)(encoded_divisor & 0xFFFF);
- *index = (unsigned short)(encoded_divisor >> 16);
+ if(ftdi->type == TYPE_2232C) {
+ *index = (unsigned short)(encoded_divisor >> 8);
+ *index &= 0xFF00;
+ *index |= ftdi->interface;
+ }
+ else
+ *index = (unsigned short)(encoded_divisor >> 16);
+
// Return the nearest baud rate
return best_baud;
}
baudrate = baudrate*4;
}
- actual_baudrate = convert_baudrate(baudrate, ftdi->type == TYPE_AM ? 1 : 0, &value, &index);
+ actual_baudrate = ftdi_convert_baudrate(baudrate, ftdi, &value, &index);
if (actual_baudrate <= 0) {
ftdi->error_str = "Silly baudrate <= 0.";
return -1;
}
-int ftdi_readt_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
+int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
*chunksize = ftdi->readbuffer_chunksize;
return 0;
}
void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom) {
- eeprom->vendor_id = 0403;
- eeprom->product_id = 6001;
+ eeprom->vendor_id = 0x0403;
+ eeprom->product_id = 0x6001;
eeprom->self_powered = 1;
eeprom->remote_wakeup = 1;
eeprom->use_serial = 0;
eeprom->change_usb_version = 0;
- eeprom->usb_version = 200;
+ eeprom->usb_version = 0x0200;
eeprom->max_power = 0;
eeprom->manufacturer = NULL;