X-Git-Url: http://developer.intra2net.com/git/?a=blobdiff_plain;f=src%2Fftdi.c;h=142d37f3de433aa485b0f5b1c2e552efe7595299;hb=c1c3d564726551454151e083c1270ba5a8d16425;hp=1e514d6fd6ed2348b356f39c9b598e35862cfe62;hpb=0fc2170ca72171271792ce9c42d7c55ede1fa4d4;p=libftdi diff --git a/src/ftdi.c b/src/ftdi.c index 1e514d6..142d37f 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -257,8 +257,10 @@ void ftdi_set_usbdev (struct ftdi_context *ftdi, libusb_device_handle *usb) /** - Finds all ftdi devices on the usb bus. Creates a new ftdi_device_list which - needs to be deallocated by ftdi_list_free() after use. + Finds all ftdi devices with given VID:PID on the usb bus. Creates a new + ftdi_device_list which needs to be deallocated by ftdi_list_free() after + use. With VID:PID 0:0, search for the default devices + (0x403:0x6001, 0x403:0x6010, 0x403:0x6011, 0x403:0x6014) \param ftdi pointer to ftdi_context \param devlist Pointer where to store list of found devices @@ -291,7 +293,11 @@ int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devli if (libusb_get_device_descriptor(dev, &desc) < 0) ftdi_error_return_free_device_list(-6, "libusb_get_device_descriptor() failed", devs); - if (desc.idVendor == vendor && desc.idProduct == product) + if (((vendor != 0 && product != 0) && + desc.idVendor == vendor && desc.idProduct == product) || + ((vendor == 0 && product == 0) && + (desc.idVendor == 0x403) && (desc.idProduct == 0x6001 || desc.idProduct == 0x6010 + || desc.idProduct == 0x6011 || desc.idProduct == 0x6014))) { *curdev = (struct ftdi_device_list*)malloc(sizeof(struct ftdi_device_list)); if (!*curdev) @@ -299,7 +305,7 @@ int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devli (*curdev)->next = NULL; (*curdev)->dev = dev; - + libusb_ref_device(dev); curdev = &(*curdev)->next; count++; } @@ -320,6 +326,7 @@ void ftdi_list_free(struct ftdi_device_list **devlist) for (curdev = *devlist; curdev != NULL;) { next = curdev->next; + libusb_unref_device(curdev->dev); free(curdev); curdev = next; } @@ -611,7 +618,6 @@ int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product) \retval -7: set baudrate failed \retval -8: get product description failed \retval -9: get serial number failed - \retval -11: libusb_init() failed \retval -12: libusb_get_device_list() failed \retval -13: libusb_get_device_descriptor() failed */ @@ -656,9 +662,6 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, if (ftdi == NULL) ftdi_error_return(-11, "ftdi context invalid"); - if (libusb_init(&ftdi->usb_ctx) < 0) - ftdi_error_return(-11, "libusb_init() failed"); - if (libusb_get_device_list(ftdi->usb_ctx, &devs) < 0) ftdi_error_return(-12, "libusb_get_device_list() failed"); @@ -734,7 +737,6 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, \note The description format may be extended in later versions. \retval 0: all fine - \retval -1: libusb_init() failed \retval -2: libusb_get_device_list() failed \retval -3: usb device not found \retval -4: unable to open device @@ -762,9 +764,6 @@ int ftdi_usb_open_string(struct ftdi_context *ftdi, const char* description) unsigned int bus_number, device_address; int i = 0; - if (libusb_init (&ftdi->usb_ctx) < 0) - ftdi_error_return(-1, "libusb_init() failed"); - if (libusb_get_device_list(ftdi->usb_ctx, &devs) < 0) ftdi_error_return(-2, "libusb_get_device_list() failed"); @@ -1076,7 +1075,7 @@ static int ftdi_convert_baudrate(int baudrate, struct ftdi_context *ftdi, } // Split into "value" and "index" values *value = (unsigned short)(encoded_divisor & 0xFFFF); - if (ftdi->type == TYPE_2232C || ftdi->type == TYPE_2232H || ftdi->type == TYPE_4232H) + if (ftdi->type == TYPE_2232C || ftdi->type == TYPE_2232H || ftdi->type == TYPE_4232H || ftdi->type == TYPE_232H ) { *index = (unsigned short)(encoded_divisor >> 8); *index &= 0xFF00; @@ -2354,6 +2353,9 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) case TYPE_4232H: user_area_size = 86; break; + case TYPE_232H: + user_area_size = 80; + break; default: user_area_size = 0; break; @@ -2537,7 +2539,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) break; case TYPE_2232C: - output[0x00] = (1<<(eeprom->channel_a_type)) & 0x7; + output[0x00] = (eeprom->channel_a_type)?((1<<(eeprom->channel_a_type)) & 0x7):0; if ( eeprom->channel_a_driver == DRIVER_VCP) output[0x00] |= DRIVER_VCP; else @@ -2548,7 +2550,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) else output[0x00] &= ~HIGH_CURRENT_DRIVE; - output[0x01] = (1<<(eeprom->channel_b_type)) & 0x7; + output[0x01] = (eeprom->channel_b_type)?((1<<(eeprom->channel_b_type)) & 0x7):0; if ( eeprom->channel_b_driver == DRIVER_VCP) output[0x01] |= DRIVER_VCP; else @@ -2619,13 +2621,13 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) output[0x16] = eeprom->cbus_function[4]; break; case TYPE_2232H: - output[0x00] = (1<<(eeprom->channel_a_type)) & 0x7; + output[0x00] = (eeprom->channel_a_type)?((1<<(eeprom->channel_a_type)) & 0x7):0; if ( eeprom->channel_a_driver == DRIVER_VCP) output[0x00] |= DRIVER_VCP; else output[0x00] &= ~DRIVER_VCP; - output[0x01] = (1<<(eeprom->channel_b_type)) & 0x7; + output[0x01] = (eeprom->channel_b_type)?((1<<(eeprom->channel_b_type)) & 0x7):0; if ( eeprom->channel_b_driver == DRIVER_VCP) output[0x01] |= DRIVER_VCP; else @@ -2684,7 +2686,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) fprintf(stderr,"FIXME: Build FT4232H specific EEPROM settings\n"); break; case TYPE_232H: - output[0x00] = (1<<(eeprom->channel_a_type)) & 0xf; + output[0x00] = (eeprom->channel_a_type)?((1<<(eeprom->channel_a_type)) & 0xf):0; if ( eeprom->channel_a_driver == DRIVER_VCP) output[0x00] |= DRIVER_VCPH; else @@ -3182,6 +3184,9 @@ int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu case IN_IS_ISOCHRONOUS: *value = ftdi->eeprom->in_is_isochronous; break; + case OUT_IS_ISOCHRONOUS: + *value = ftdi->eeprom->out_is_isochronous; + break; case SUSPEND_PULL_DOWNS: *value = ftdi->eeprom->suspend_pull_downs; break; @@ -3191,6 +3196,9 @@ int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu case USB_VERSION: *value = ftdi->eeprom->usb_version; break; + case USE_USB_VERSION: + *value = ftdi->eeprom->use_usb_version; + break; case MAX_POWER: *value = ftdi->eeprom->max_power; break; @@ -3345,6 +3353,9 @@ int ftdi_set_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu case IN_IS_ISOCHRONOUS: ftdi->eeprom->in_is_isochronous = value; break; + case OUT_IS_ISOCHRONOUS: + ftdi->eeprom->out_is_isochronous = value; + break; case SUSPEND_PULL_DOWNS: ftdi->eeprom->suspend_pull_downs = value; break; @@ -3354,6 +3365,9 @@ int ftdi_set_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu case USB_VERSION: ftdi->eeprom->usb_version = value; break; + case USE_USB_VERSION: + ftdi->eeprom->use_usb_version = value; + break; case MAX_POWER: ftdi->eeprom->max_power = value; break; @@ -3497,6 +3511,29 @@ int ftdi_get_eeprom_buf(struct ftdi_context *ftdi, unsigned char * buf, int size return 0; } +/** Set the EEPROM content from the user-supplied prefilled buffer + + \param ftdi pointer to ftdi_context + \param buf buffer to read EEPROM content + \param size Size of buffer + + \retval 0: All fine + \retval -1: struct ftdi_contxt or ftdi_eeprom of buf missing +*/ +int ftdi_set_eeprom_buf(struct ftdi_context *ftdi, const unsigned char * buf, int size) +{ + if (!ftdi || !(ftdi->eeprom) || !buf) + ftdi_error_return(-1, "No appropriate structure"); + + // Only copy up to FTDI_MAX_EEPROM_SIZE bytes + if (size > FTDI_MAX_EEPROM_SIZE) + size = FTDI_MAX_EEPROM_SIZE; + + memcpy(ftdi->eeprom->buf, buf, size); + + return 0; +} + /** Read eeprom location