X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=blobdiff_plain;f=src%2Fftdi.c;h=52266d0313010a609ae426e3c616e9bc91f39fee;hp=ac8f18a347bd5d10833839381a6dab746a523a2f;hb=5bf1c1e3ff1616fda20c26cc3e3df7b807744c99;hpb=4fe1a3f009f8591a1b6ac157a073d60fbd151c91 diff --git a/src/ftdi.c b/src/ftdi.c index ac8f18a..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"); @@ -825,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 @@ -845,7 +851,7 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, \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; @@ -859,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); @@ -1908,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)"); @@ -2262,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 @@ -2284,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