ftdi.c - description
-------------------
begin : Fri Apr 4 2003
- copyright : (C) 2003-2014 by Intra2net AG and the libftdi developers
+ copyright : (C) 2003-2017 by Intra2net AG and the libftdi developers
email : opensource@intra2net.com
***************************************************************************/
\mainpage libftdi API documentation
Library to talk to FTDI chips. You find the latest versions of libftdi at
- http://www.intra2net.com/en/developer/libftdi/
+ https://www.intra2net.com/en/developer/libftdi/
The library is easy to use. Have a look at this short example:
\include simple.c
*/
int ftdi_init(struct ftdi_context *ftdi)
{
- struct ftdi_eeprom* eeprom = (struct ftdi_eeprom *)malloc(sizeof(struct ftdi_eeprom));
+ struct ftdi_eeprom* eeprom;
ftdi->usb_ctx = NULL;
ftdi->usb_dev = NULL;
ftdi->usb_read_timeout = 5000;
ftdi_set_interface(ftdi, INTERFACE_ANY);
ftdi->bitbang_mode = 1; /* when bitbang is enabled this holds the number of the mode */
+ eeprom = (struct ftdi_eeprom *)malloc(sizeof(struct ftdi_eeprom));
if (eeprom == 0)
ftdi_error_return(-2, "Can't malloc struct ftdi_eeprom");
memset(eeprom, 0, sizeof(struct ftdi_eeprom));
if (libusb_detach_kernel_driver(ftdi->usb_dev, ftdi->interface) !=0)
detach_errno = errno;
}
+ else if (ftdi->module_detach_mode == AUTO_DETACH_REATACH_SIO_MODULE)
+ {
+ if (libusb_set_auto_detach_kernel_driver(ftdi->usb_dev, 1) != LIBUSB_SUCCESS)
+ detach_errno = errno;
+ }
if (libusb_get_configuration (ftdi->usb_dev, &cfg) < 0)
ftdi_error_return(-12, "libusb_get_configuration () failed");
\retval -9: get serial number failed
\retval -10: unable to close device
\retval -11: ftdi context invalid
+ \retval -12: libusb_get_device_list() failed
*/
int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product,
const char* description, const char* serial, unsigned int index)
}
/**
+ Opens the device at a given USB bus and device address.
+
+ \param ftdi pointer to ftdi_context
+ \param bus Bus number
+ \param addr Device address
+
+ \retval 0: all fine
+ \retval -1: usb_find_busses() failed
+ \retval -2: usb_find_devices() failed
+ \retval -3: usb device not found
+ \retval -4: unable to open device
+ \retval -5: unable to claim device
+ \retval -6: reset failed
+ \retval -7: set baudrate failed
+ \retval -8: get product description failed
+ \retval -9: get serial number failed
+ \retval -10: unable to close device
+ \retval -11: ftdi context invalid
+ \retval -12: libusb_get_device_list() failed
+*/
+int ftdi_usb_open_bus_addr(struct ftdi_context *ftdi, uint8_t bus, uint8_t addr)
+{
+ libusb_device *dev;
+ libusb_device **devs;
+ int i = 0;
+
+ if (ftdi == NULL)
+ ftdi_error_return(-11, "ftdi context invalid");
+
+ if (libusb_get_device_list(ftdi->usb_ctx, &devs) < 0)
+ ftdi_error_return(-12, "libusb_get_device_list() failed");
+
+ while ((dev = devs[i++]) != NULL)
+ {
+ if (libusb_get_bus_number(dev) == bus && libusb_get_device_address(dev) == addr)
+ {
+ int res;
+ res = ftdi_usb_open_dev(ftdi, dev);
+ libusb_free_device_list(devs,1);
+ return res;
+ }
+ }
+
+ // device not found
+ ftdi_error_return_free_device_list(-3, "device not found", devs);
+}
+
+/**
Opens the ftdi-device described by a description-string.
Intended to be used for parsing a device-description given as commandline argument.
int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
{
int offset = 0, ret, i, num_of_chunks, chunk_remains;
- int packet_size = ftdi->max_packet_size;
+ int packet_size;
int actual_length = 1;
if (ftdi == NULL || ftdi->usb_dev == NULL)
ftdi_error_return(-666, "USB device unavailable");
// Packet size sanity check (avoid division by zero)
+ packet_size = ftdi->max_packet_size;
if (packet_size == 0)
ftdi_error_return(-1, "max_packet_size is bogus (zero)");
/**
Set flowcontrol for ftdi chip
+ Note: Do not use this function to enable XON/XOFF mode, use ftdi_setflowctrl_xonxoff() instead.
+
\param ftdi pointer to ftdi_context
\param flowctrl flow control to use. should be
- SIO_DISABLE_FLOW_CTRL, SIO_RTS_CTS_HS, SIO_DTR_DSR_HS or SIO_XON_XOFF_HS
+ SIO_DISABLE_FLOW_CTRL, SIO_RTS_CTS_HS, SIO_DTR_DSR_HS
\retval 0: all fine
\retval -1: set flow control failed
}
/**
+ Set XON/XOFF flowcontrol for ftdi chip
+
+ \param ftdi pointer to ftdi_context
+ \param xon character code used to resume transmission
+ \param xoff character code used to pause transmission
+
+ \retval 0: all fine
+ \retval -1: set flow control failed
+ \retval -2: USB device unavailable
+*/
+int ftdi_setflowctrl_xonxoff(struct ftdi_context *ftdi, unsigned char xon, unsigned char xoff)
+{
+ if (ftdi == NULL || ftdi->usb_dev == NULL)
+ ftdi_error_return(-2, "USB device unavailable");
+
+ uint16_t xonxoff = xon | (xoff << 8);
+ if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
+ SIO_SET_FLOW_CTRL_REQUEST, xonxoff, (SIO_XON_XOFF_HS | ftdi->index),
+ NULL, 0, ftdi->usb_write_timeout) < 0)
+ ftdi_error_return(-1, "set flow control failed");
+
+ return 0;
+}
+
+/**
Set dtr line
\param ftdi pointer to ftdi_context
return 0;
}
+/**
+ Return device ID strings from the eeprom. Device needs to be connected.
+
+ The parameters manufacturer, description and serial may be NULL
+ or pointer to buffers to store the fetched strings.
+
+ \param ftdi pointer to ftdi_context
+ \param manufacturer Store manufacturer string here if not NULL
+ \param mnf_len Buffer size of manufacturer string
+ \param product Store product description string here if not NULL
+ \param prod_len Buffer size of product description string
+ \param serial Store serial string here if not NULL
+ \param serial_len Buffer size of serial string
+
+ \retval 0: all fine
+ \retval -1: ftdi context invalid
+ \retval -2: ftdi eeprom buffer invalid
+*/
+int ftdi_eeprom_get_strings(struct ftdi_context *ftdi,
+ char *manufacturer, int mnf_len,
+ char *product, int prod_len,
+ char *serial, int serial_len)
+{
+ struct ftdi_eeprom *eeprom;
+
+ if (ftdi == NULL)
+ ftdi_error_return(-1, "No struct ftdi_context");
+ if (ftdi->eeprom == NULL)
+ ftdi_error_return(-2, "No struct ftdi_eeprom");
+
+ eeprom = ftdi->eeprom;
+
+ if (manufacturer)
+ {
+ strncpy(manufacturer, eeprom->manufacturer, mnf_len);
+ if (mnf_len > 0)
+ manufacturer[mnf_len - 1] = '\0';
+ }
+
+ if (product)
+ {
+ strncpy(product, eeprom->product, prod_len);
+ if (prod_len > 0)
+ product[prod_len - 1] = '\0';
+ }
+
+ if (serial)
+ {
+ strncpy(serial, eeprom->serial, serial_len);
+ if (serial_len > 0)
+ serial[serial_len - 1] = '\0';
+ }
+
+ return 0;
+}
/*FTD2XX doesn't check for values not fitting in the ACBUS Signal options*/
void set_ft232h_cbus(struct ftdi_eeprom *eeprom, unsigned char * output)
break;
case TYPE_230X:
output[0x00] = 0x80; /* Actually, leave the default value */
- output[0x0a] = 0x08; /* Enable USB Serial Number */
/*FIXME: Make DBUS & CBUS Control configurable*/
output[0x0c] = 0; /* DBUS drive 4mA, CBUS drive 4 mA like factory default */
for (j = 0; j <= 6; j++)