X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=blobdiff_plain;f=src%2Fftdi.c;h=52266d0313010a609ae426e3c616e9bc91f39fee;hp=c26ab723a16244a65a02b67f16d7f1a2a3a6dfb5;hb=bfbd47b7de65aa41c433945283d7bc0ebfa5576a;hpb=814e69f509963067d3b1432269e96c667ed31dda diff --git a/src/ftdi.c b/src/ftdi.c index c26ab72..52266d0 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -87,7 +87,7 @@ static void ftdi_usb_close_internal (struct ftdi_context *ftdi) */ 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; @@ -111,6 +111,7 @@ int ftdi_init(struct ftdi_context *ftdi) 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)); @@ -613,6 +614,11 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, libusb_device *dev) 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"); @@ -750,6 +756,7 @@ int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, \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) @@ -824,11 +831,11 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, } /** - Opens the device at a given USB bus and port. + Opens the device at a given USB bus and device address. \param ftdi pointer to ftdi_context \param bus Bus number - \param port Port number + \param addr Device address \retval 0: all fine \retval -1: usb_find_busses() failed @@ -842,8 +849,9 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, \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_port(struct ftdi_context *ftdi, uint8_t bus, uint8_t port) +int ftdi_usb_open_bus_addr(struct ftdi_context *ftdi, uint8_t bus, uint8_t addr) { libusb_device *dev; libusb_device **devs; @@ -857,7 +865,7 @@ int ftdi_usb_open_bus_port(struct ftdi_context *ftdi, uint8_t bus, uint8_t port) while ((dev = devs[i++]) != NULL) { - if (libusb_get_bus_number(dev) == bus && libusb_get_port_number(dev) == port) + if (libusb_get_bus_number(dev) == bus && libusb_get_device_address(dev) == addr) { int res; res = ftdi_usb_open_dev(ftdi, dev); @@ -1906,13 +1914,14 @@ int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunk 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)"); @@ -2260,9 +2269,11 @@ int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short *status) /** 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 @@ -2282,6 +2293,31 @@ int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl) } /** + 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