X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=blobdiff_plain;f=src%2Fftdi.c;h=355ea587e9f2505716098b52fcde9067c23197ab;hp=e38122b8e9b18cd3383beaf10c0eb510b2b305f7;hb=db099ec562c4e0199c6ec2c71020612e3623f036;hpb=f6ef2983ec626387a30502e0369ef4d79cb1bdce diff --git a/src/ftdi.c b/src/ftdi.c index e38122b..355ea58 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -2210,7 +2210,7 @@ void ftdi_eeprom_initdefaults(struct ftdi_context *ftdi) { eeprom->cbus_function[i] = 0; } - eeprom->high_current = 0; + eeprom->high_current_a = 0; eeprom->invert = 0; eeprom->size = FTDI_MAX_EEPROM_SIZE; @@ -2291,7 +2291,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) if (ftdi->type != TYPE_R) { if (eeprom->invert) return -4; - if (eeprom->high_current) return -5; + if (eeprom->high_current_a) return -5; } size_check = eeprom->size; @@ -2314,7 +2314,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) memset (output, 0, eeprom->size); // Addr 00: High current IO - output[0x00] = eeprom->high_current ? HIGH_CURRENT_DRIVE : 0; + output[0x00] = eeprom->high_current_a ? HIGH_CURRENT_DRIVE : 0; // Addr 01: IN endpoint size (for R type devices, different for FT2232) if (ftdi->type == TYPE_R) { output[0x01] = 0x40; @@ -2506,6 +2506,18 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, eeprom_size = 0x80; eeprom = ftdi->eeprom; + // Addr 00: Channel A setting + + eeprom->channel_a_type = buf[0x00] & 0x7; + eeprom->channel_a_driver = buf[0x00] & DRIVER_VCP; + eeprom->high_current_a = buf[0x00] & HIGH_CURRENT_DRIVE; + + // Addr 01: Channel B setting + + eeprom->channel_b_type = buf[0x01] & 0x7; + eeprom->channel_b_driver = buf[0x01] & DRIVER_VCP; + eeprom->high_current_b = buf[0x01] & HIGH_CURRENT_DRIVE; + // Addr 02: Vendor ID eeprom->vendor_id = buf[0x02] + (buf[0x03] << 8); @@ -2530,24 +2542,22 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, // Bit 6: 0 - reserved // Bit 5: 0 - reserved // Bit 4: 1 - Change USB version + // Not seen on FT2232(D) // Bit 3: 1 - Use the serial number string // Bit 2: 1 - Enable suspend pull downs for lower power // Bit 1: 1 - Out EndPoint is Isochronous // Bit 0: 1 - In EndPoint is Isochronous // - j = buf[0x0A]; - if (j&0x01) eeprom->in_is_isochronous = 1; - if (j&0x02) eeprom->out_is_isochronous = 1; - if (j&0x04) eeprom->suspend_pull_downs = 1; - if (j&0x08) eeprom->use_serial = 1; - if (j&0x10) eeprom->change_usb_version = 1; + eeprom->in_is_isochronous = buf[0x0A]&0x01; + eeprom->out_is_isochronous = buf[0x0A]&0x02; + eeprom->suspend_pull_downs = buf[0x0A]&0x04; + eeprom->use_serial = buf[0x0A]&0x08; + eeprom->change_usb_version = buf[0x0A]&0x10; - // Addr 0B: Invert data lines - eeprom->invert = buf[0x0B]; // Addr 0C: USB version low byte when 0x0A bit 4 is set // Addr 0D: USB version high byte when 0x0A bit 4 is set - if (eeprom->change_usb_version == 1) + if ((eeprom->change_usb_version == 1) || ftdi->type == TYPE_2232C) { eeprom->usb_version = buf[0x0C] + (buf[0x0D] << 8); } @@ -2561,7 +2571,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, if (eeprom->manufacturer) { // Decode manufacturer - i = buf[0x0E]; // offset + i = buf[0x0E] & (eeprom_size -1); // offset for (j=0;jmanufacturer[j] = buf[2*j+i+2]; @@ -2580,7 +2590,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, if(eeprom->product) { // Decode product name - i = buf[0x10]; // offset + i = buf[0x10] & (eeprom_size -1); // offset for (j=0;jproduct[j] = buf[2*j+i+2]; @@ -2599,7 +2609,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, if(eeprom->serial) { // Decode serial - i = buf[0x12]; // offset + i = buf[0x12] & (eeprom_size -1); // offset for (j=0;jserial[j] = buf[2*j+i+2]; @@ -2629,29 +2639,47 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, ftdi_error_return(-1,"EEPROM checksum error"); } - if ((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM) || (ftdi->type == TYPE_2232C)) + else if ((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM)) { eeprom->chip = buf[14]; } - if(ftdi->type == TYPE_2) + else if(ftdi->type == TYPE_2232C) { - if(ftdi->type == TYPE_R) + eeprom->chip = buf[14]; + } + else if(ftdi->type == TYPE_R) { + // Addr 0B: Invert data lines + // Works only on FT232R, not FT245R, but no way to distinguish + eeprom->invert = buf[0x0B]; // Addr 14: CBUS function: CBUS0, CBUS1 // Addr 15: CBUS function: CBUS2, CBUS3 // Addr 16: CBUS function: CBUS5 - if (ftdi->type == TYPE_R) { - eeprom->cbus_function[0] = buf[0x14] & 0x0f; - eeprom->cbus_function[1] = (buf[0x14] >> 4) & 0x0f; - eeprom->cbus_function[2] = buf[0x15] & 0x0f; - eeprom->cbus_function[3] = (buf[0x15] >> 4) & 0x0f; - eeprom->cbus_function[4] = buf[0x16] & 0x0f; - } else { - for (j=0; j<5; j++) eeprom->cbus_function[j] = 0; - } + eeprom->cbus_function[0] = buf[0x14] & 0x0f; + eeprom->cbus_function[1] = (buf[0x14] >> 4) & 0x0f; + eeprom->cbus_function[2] = buf[0x15] & 0x0f; + eeprom->cbus_function[3] = (buf[0x15] >> 4) & 0x0f; + eeprom->cbus_function[4] = buf[0x16] & 0x0f; + } + else if ((ftdi->type == TYPE_2232H) ||(ftdi->type == TYPE_4232H)) + { + eeprom->group0_drive = buf[0x0c] & DRIVE_16MA; + eeprom->group0_schmitt = buf[0x0c] & IS_SCHMITT; + eeprom->group0_slew = buf[0x0c] & SLOW_SLEW; + eeprom->group1_drive = (buf[0x0c] >> 4) & 0x3; + eeprom->group1_schmitt = (buf[0x0c] >> 4) & IS_SCHMITT; + eeprom->group1_slew = (buf[0x0c] >> 4) & SLOW_SLEW; + eeprom->group2_drive = buf[0x0d] & DRIVE_16MA; + eeprom->group2_schmitt = buf[0x0d] & IS_SCHMITT; + eeprom->group2_slew = buf[0x0d] & SLOW_SLEW; + eeprom->group3_drive = (buf[0x0d] >> 4) & DRIVE_16MA; + eeprom->group3_schmitt = (buf[0x0d] >> 4) & IS_SCHMITT; + eeprom->group3_slew = (buf[0x0d] >> 4) & SLOW_SLEW; } + if(verbose) { + char *channel_mode[] = {"UART","245","CPU", "unknown", "OPTO"}; 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); @@ -2667,7 +2695,40 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, fprintf(stdout, "Product: %s\n",eeprom->product); if(eeprom->serial) fprintf(stdout, "Serial: %s\n",eeprom->serial); - fprintf(stderr, "Checksum : %04x %04x\n", checksum); + fprintf(stdout, "Checksum : %04x\n", checksum); + if (ftdi->type >= TYPE_2232C) + fprintf(stdout,"Channel A has Mode %s%s%s\n", + channel_mode[eeprom->channel_a_type], + (eeprom->channel_a_driver)?" VCP":"", + (eeprom->high_current_a)?" High Currenr IO":""); + if (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 Currenr IO":""); + if ((ftdi->type == TYPE_2232H) || (ftdi->type == TYPE_4232H)) + { + fprintf(stdout,"%s has %d mA drive%s%s\n", + (ftdi->type == TYPE_2232H)?"AL":"A", + (eeprom->group0_drive+1) *4, + (eeprom->group0_schmitt)?" Schmitt Input":"", + (eeprom->group0_slew)?" Slow Slew":""); + fprintf(stdout,"%s has %d mA drive%s%s\n", + (ftdi->type == TYPE_2232H)?"AH":"B", + (eeprom->group1_drive+1) *4, + (eeprom->group1_schmitt)?" Schmitt Input":"", + (eeprom->group1_slew)?" Slow Slew":""); + fprintf(stdout,"%s has %d mA drive%s%s\n", + (ftdi->type == TYPE_2232H)?"BL":"C", + (eeprom->group2_drive+1) *4, + (eeprom->group2_schmitt)?" Schmitt Input":"", + (eeprom->group2_slew)?" Slow Slew":""); + fprintf(stdout,"%s has %d mA drive%s%s\n", + (ftdi->type == TYPE_2232H)?"BH":"D", + (eeprom->group3_drive+1) *4, + (eeprom->group3_schmitt)?" Schmitt Input":"", + (eeprom->group3_slew)?" Slow Slew":""); + } }