X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=blobdiff_plain;f=src%2Fftdi.c;h=0a7fb274dd927d45615bbd26c11e950155164e46;hp=92c5fae79670e0eac21e5d85b245ae7a4ccb8235;hb=HEAD;hpb=32e899fa5ecd30aad0a25ea8d7e208d203aaa0ae diff --git a/src/ftdi.c b/src/ftdi.c index 92c5fae..534e3dd 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -83,7 +83,7 @@ static void ftdi_usb_close_internal (struct ftdi_context *ftdi) \retval 0: all fine \retval -1: couldn't allocate read buffer - \retval -2: couldn't allocate struct buffer + \retval -2: couldn't allocate struct buffer \retval -3: libusb_init() failed \remark This should be called before all functions @@ -112,7 +112,7 @@ int ftdi_init(struct ftdi_context *ftdi) ftdi_error_return(-3, "libusb_init() failed"); ftdi_set_interface(ftdi, INTERFACE_ANY); - ftdi->bitbang_mode = 1; /* when bitbang is enabled this holds the number of the mode */ + 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) @@ -298,7 +298,7 @@ struct ftdi_version_info ftdi_get_library_version(void) /** 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 + use. With VID:PID 0:0, search for the default devices (0x403:0x6001, 0x403:0x6010, 0x403:0x6011, 0x403:0x6014, 0x403:0x6015) \param ftdi pointer to ftdi_context @@ -639,7 +639,7 @@ int ftdi_usb_open_dev(struct ftdi_context *ftdi, libusb_device *dev) ftdi_error_return(-12, "libusb_get_configuration () failed"); // set configuration (needed especially for windows) // tolerate EBUSY: one device with one configuration, but two interfaces - // and libftdi sessions to both interfaces (e.g. FT2232) + // and libftdi sessions to both interfaces (e.g. FT2232) if (desc.bNumConfigurations > 0 && cfg != cfg0) { if (libusb_set_configuration(ftdi->usb_dev, cfg0) < 0) @@ -1316,7 +1316,7 @@ static int ftdi_to_clkbits_AM(int baudrate, unsigned long *encoded_divisor) return best_baud; } -/* ftdi_to_clkbits Convert a requested baudrate for a given system clock and predivisor +/* ftdi_to_clkbits Convert a requested baudrate for a given system clock and predivisor to encoded divisor and the achievable baudrate Function is only used internally \internal @@ -2218,6 +2218,24 @@ int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned } /** + Set module detach mode. + + \param ftdi pointer to ftdi_context + \param mode detach mode to use. + + \retval 0: all fine + \retval -1: can't enable bitbang mode +*/ +int ftdi_set_module_detach_mode(struct ftdi_context *ftdi, enum ftdi_module_detach_mode mode) +{ + if (ftdi == NULL) + ftdi_error_return(-1, "FTDI context invalid"); + + ftdi->module_detach_mode = mode; + return 0; +} + +/** Disable bitbang mode. \param ftdi pointer to ftdi_context @@ -3049,7 +3067,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) // Dynamic content // Strings start at 0x94 (TYPE_AM, TYPE_BM) // 0x96 (TYPE_2232C), 0x98 (TYPE_R) and 0x9a (TYPE_x232H) - // 0xa0 (TYPE_232H) + // 0xa0 (TYPE_232H, TYPE_230X) i = 0; switch (ftdi->type) { @@ -3072,7 +3090,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) i = 0xa0; break; } - /* Wrap around 0x80 for 128 byte EEPROMS (Internale and 93x46) */ + /* Wrap around 0x80 for 128 byte EEPROMS (Internal and 93x46) */ eeprom_size_mask = eeprom->size -1; free_end = i & eeprom_size_mask; @@ -3103,16 +3121,16 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) if (eeprom->use_serial) { // Addr 12: Offset of the serial string + 0x80, calculated later - // Addr 13: Length of serial string - output[0x12] = i | 0x80; // calculate offset - output[i & eeprom_size_mask] = serial_size*2 + 2, i++; - output[i & eeprom_size_mask] = 0x03, i++; - for (j = 0; j < serial_size; j++) - { - output[i & eeprom_size_mask] = eeprom->serial[j], i++; - output[i & eeprom_size_mask] = 0x00, i++; - } - output[0x13] = serial_size*2 + 2; + // Addr 13: Length of serial string + output[0x12] = i | 0x80; // calculate offset + output[i & eeprom_size_mask] = serial_size*2 + 2, i++; + output[i & eeprom_size_mask] = 0x03, i++; + for (j = 0; j < serial_size; j++) + { + output[i & eeprom_size_mask] = eeprom->serial[j], i++; + output[i & eeprom_size_mask] = 0x00, i++; + } + output[0x13] = serial_size*2 + 2; } // Legacy port name and PnP fields for FT2232 and newer chips @@ -3125,6 +3143,8 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) i++; output[i & eeprom_size_mask] = eeprom->is_not_pnp; /* as seen when written with FTD2XX */ i++; + output[i & eeprom_size_mask] = 0x00; + i++; } if (ftdi->type > TYPE_AM) /* use_serial not used in AM devices */ @@ -3136,7 +3156,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) } /* Bytes and Bits specific to (some) types - Write linear, as this allows easier fixing*/ + Write linear, as this allows easier fixing */ switch (ftdi->type) { case TYPE_AM: @@ -3208,7 +3228,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) if (eeprom->external_oscillator) output[0x00] |= 0x02; - output[0x01] = 0x40; /* Hard coded Endpoint Size*/ + output[0x01] = 0x40; /* Hard coded Endpoint Size */ if (eeprom->suspend_pull_downs) output[0x0A] |= 0x4; @@ -3440,7 +3460,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) case TYPE_230X: output[0x00] = 0x80; /* Actually, leave the default value */ /*FIXME: Make DBUS & CBUS Control configurable*/ - output[0x0c] = 0; /* DBUS drive 4mA, CBUS drive 4 mA like factory default */ + output[0x0c] = 0; /* DBUS drive 4mA, CBUS drive 4mA like factory default */ for (j = 0; j <= 6; j++) { output[0x1a + j] = eeprom->cbus_function[j]; @@ -3503,6 +3523,8 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) i = 0x50; } value = data; + output[i * 2] = data; + output[(i * 2) + 1] = data >> 8; } else { value = output[i*2]; @@ -3876,11 +3898,18 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) (eeprom->data_order)?"LSB":"MSB", (eeprom->flow_control)?"":"No "); } - if ((ftdi->type == TYPE_2232H) || (ftdi->type == TYPE_4232H)) + if ((ftdi->type == TYPE_2232H) || (ftdi->type == TYPE_4232H) || (ftdi->type == TYPE_2232C)) fprintf(stdout,"Channel B has Mode %s%s%s\n", channel_mode[eeprom->channel_b_type], (eeprom->channel_b_driver)?" VCP":"", (eeprom->high_current_b)?" High Current IO":""); + if (ftdi->type == TYPE_4232H) + { + fprintf(stdout,"Channel C has Mode UART%s\n", + (eeprom->channel_c_driver)?" VCP":""); + fprintf(stdout,"Channel D has Mode UART%s\n", + (eeprom->channel_d_driver)?" VCP":""); + } if (((ftdi->type == TYPE_BM) || (ftdi->type == TYPE_2232C)) && eeprom->use_usb_version) fprintf(stdout,"Use explicit USB Version %04x\n",eeprom->usb_version); @@ -4172,6 +4201,9 @@ int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu case EXTERNAL_OSCILLATOR: *value = ftdi->eeprom->external_oscillator; break; + case USER_DATA_ADDR: + *value = ftdi->eeprom->user_data_addr; + break; default: ftdi_error_return(-1, "Request for unknown EEPROM value"); }