X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=blobdiff_plain;f=src%2Fftdi.c;h=ac8f18a347bd5d10833839381a6dab746a523a2f;hp=f5d263cc1983ceabe08158f9eb24e61fe3fb7dd7;hb=4fe1a3f009f8591a1b6ac157a073d60fbd151c91;hpb=6f9f969dc7e359296e562ee9731081cefaf06b20 diff --git a/src/ftdi.c b/src/ftdi.c index f5d263c..ac8f18a 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -2,7 +2,7 @@ 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 ***************************************************************************/ @@ -18,7 +18,7 @@ \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 @@ -469,11 +469,12 @@ int ftdi_usb_get_strings2(struct ftdi_context *ftdi, struct libusb_device *dev, char *serial, int serial_len) { struct libusb_device_descriptor desc; + char need_open; if ((ftdi==NULL) || (dev==NULL)) return -1; - char need_open = (ftdi->usb_dev == NULL); + need_open = (ftdi->usb_dev == NULL); if (need_open && libusb_open(dev, &ftdi->usb_dev) < 0) ftdi_error_return(-4, "libusb_open() failed"); @@ -749,6 +750,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) @@ -823,6 +825,54 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, } /** + Opens the device at a given USB bus and port. + + \param ftdi pointer to ftdi_context + \param bus Bus number + \param port Port number + + \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_port(struct ftdi_context *ftdi, uint8_t bus, uint8_t port) +{ + 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_port_number(dev) == port) + { + 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. @@ -1252,7 +1302,7 @@ static int ftdi_convert_baudrate(int baudrate, struct ftdi_context *ftdi, else best_baud = ftdi_to_clkbits(baudrate, C_CLK, 16, &encoded_divisor); } - else if ((ftdi->type == TYPE_BM) || (ftdi->type == TYPE_2232C) || (ftdi->type == TYPE_R )) + else if ((ftdi->type == TYPE_BM) || (ftdi->type == TYPE_2232C) || (ftdi->type == TYPE_R) || (ftdi->type == TYPE_230X)) { best_baud = ftdi_to_clkbits(baudrate, C_CLK, 16, &encoded_divisor); } @@ -2441,7 +2491,7 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer, eeprom->manufacturer = NULL; if (manufacturer) { - eeprom->manufacturer = malloc(strlen(manufacturer)+1); + eeprom->manufacturer = (char *)malloc(strlen(manufacturer)+1); if (eeprom->manufacturer) strcpy(eeprom->manufacturer, manufacturer); } @@ -2451,7 +2501,7 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer, eeprom->product = NULL; if(product) { - eeprom->product = malloc(strlen(product)+1); + eeprom->product = (char *)malloc(strlen(product)+1); if (eeprom->product) strcpy(eeprom->product, product); } @@ -2471,7 +2521,7 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer, default: ftdi_error_return(-3, "Unknown chip type"); } - eeprom->product = malloc(strlen(default_product) +1); + eeprom->product = (char *)malloc(strlen(default_product) +1); if (eeprom->product) strcpy(eeprom->product, default_product); } @@ -2481,7 +2531,7 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer, eeprom->serial = NULL; if (serial) { - eeprom->serial = malloc(strlen(serial)+1); + eeprom->serial = (char *)malloc(strlen(serial)+1); if (eeprom->serial) strcpy(eeprom->serial, serial); } @@ -2567,7 +2617,7 @@ int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, char * manufacturer, { if (eeprom->manufacturer) free (eeprom->manufacturer); - eeprom->manufacturer = malloc(strlen(manufacturer)+1); + eeprom->manufacturer = (char *)malloc(strlen(manufacturer)+1); if (eeprom->manufacturer) strcpy(eeprom->manufacturer, manufacturer); } @@ -2576,7 +2626,7 @@ int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, char * manufacturer, { if (eeprom->product) free (eeprom->product); - eeprom->product = malloc(strlen(product)+1); + eeprom->product = (char *)malloc(strlen(product)+1); if (eeprom->product) strcpy(eeprom->product, product); } @@ -2585,7 +2635,7 @@ int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, char * manufacturer, { if (eeprom->serial) free (eeprom->serial); - eeprom->serial = malloc(strlen(serial)+1); + eeprom->serial = (char *)malloc(strlen(serial)+1); if (eeprom->serial) { strcpy(eeprom->serial, serial); @@ -2595,6 +2645,61 @@ int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, char * manufacturer, 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) @@ -3180,7 +3285,6 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) 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++) @@ -3280,7 +3384,7 @@ static unsigned char bit2type(unsigned char bits) */ static void print_inverted_bits(int invert) { - char *r_bits[] = {"TXD","RXD","RTS","CTS","DTR","DSR","DCD","RI"}; + const char *r_bits[] = {"TXD","RXD","RTS","CTS","DTR","DSR","DCD","RI"}; int i; fprintf(stdout,"Inverted bits:"); @@ -3368,7 +3472,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) free(eeprom->manufacturer); if (manufacturer_size > 0) { - eeprom->manufacturer = malloc(manufacturer_size); + eeprom->manufacturer = (char *)malloc(manufacturer_size); if (eeprom->manufacturer) { // Decode manufacturer @@ -3389,7 +3493,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) product_size = buf[0x11]/2; if (product_size > 0) { - eeprom->product = malloc(product_size); + eeprom->product = (char *)malloc(product_size); if (eeprom->product) { // Decode product name @@ -3410,7 +3514,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) serial_size = buf[0x13]/2; if (serial_size > 0) { - eeprom->serial = malloc(serial_size); + eeprom->serial = (char *)malloc(serial_size); if (eeprom->serial) { // Decode serial @@ -3566,7 +3670,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) if (verbose) { - char *channel_mode[] = {"UART", "FIFO", "CPU", "OPTO", "FT1284"}; + const char *channel_mode[] = {"UART", "FIFO", "CPU", "OPTO", "FT1284"}; fprintf(stdout, "VID: 0x%04x\n",eeprom->vendor_id); fprintf(stdout, "PID: 0x%04x\n",eeprom->product_id); fprintf(stdout, "Release: 0x%04x\n",eeprom->release_number); @@ -3647,7 +3751,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) } else if (ftdi->type == TYPE_232H) { - char *cbush_mux[] = {"TRISTATE","TXLED","RXLED", "TXRXLED","PWREN", + const char *cbush_mux[] = {"TRISTATE","TXLED","RXLED", "TXRXLED","PWREN", "SLEEP","DRIVE_0","DRIVE_1","IOMODE","TXDEN", "CLK30","CLK15","CLK7_5" }; @@ -3668,7 +3772,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) } else if (ftdi->type == TYPE_230X) { - char *cbusx_mux[] = {"TRISTATE","TXLED","RXLED", "TXRXLED","PWREN", + const char *cbusx_mux[] = {"TRISTATE","TXLED","RXLED", "TXRXLED","PWREN", "SLEEP","DRIVE_0","DRIVE_1","IOMODE","TXDEN", "CLK24","CLK12","CLK6","BAT_DETECT","BAT_DETECT#", "I2C_TXE#", "I2C_RXF#", "VBUS_SENSE", "BB_WR#", @@ -3694,11 +3798,11 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) if (ftdi->type == TYPE_R) { - char *cbus_mux[] = {"TXDEN","PWREN","RXLED", "TXLED","TX+RXLED", + const char *cbus_mux[] = {"TXDEN","PWREN","RXLED", "TXLED","TX+RXLED", "SLEEP","CLK48","CLK24","CLK12","CLK6", "IOMODE","BB_WR","BB_RD" }; - char *cbus_BB[] = {"RXF","TXE","RD", "WR"}; + const char *cbus_BB[] = {"RXF","TXE","RD", "WR"}; if (eeprom->invert) print_inverted_bits(eeprom->invert); @@ -4195,12 +4299,16 @@ int ftdi_set_eeprom_user_data(struct ftdi_context *ftdi, const char * buf, int s */ int ftdi_read_eeprom_location (struct ftdi_context *ftdi, int eeprom_addr, unsigned short *eeprom_val) { + unsigned char buf[2]; + if (ftdi == NULL || ftdi->usb_dev == NULL) ftdi_error_return(-2, "USB device unavailable"); - if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, SIO_READ_EEPROM_REQUEST, 0, eeprom_addr, (unsigned char *)eeprom_val, 2, ftdi->usb_read_timeout) != 2) + if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, SIO_READ_EEPROM_REQUEST, 0, eeprom_addr, buf, 2, ftdi->usb_read_timeout) != 2) ftdi_error_return(-1, "reading eeprom failed"); + *eeprom_val = (0xff & buf[0]) | (buf[1] << 8); + return 0; } @@ -4483,7 +4591,7 @@ int ftdi_erase_eeprom(struct ftdi_context *ftdi) \retval Pointer to error string */ -char *ftdi_get_error_string (struct ftdi_context *ftdi) +const char *ftdi_get_error_string (struct ftdi_context *ftdi) { if (ftdi == NULL) return "";