X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=blobdiff_plain;f=src%2Fftdi.c;h=65a626ffa79c589d63044cc9cf914723989e7e7a;hp=9ddac9df91d0ce16613b58458643183e04d8ad55;hb=2b9a3c8226573d507149b8ca6e5a925229dd691d;hpb=e5d95e9cf85c2b19b30c224cfe6c65d29b041e82 diff --git a/src/ftdi.c b/src/ftdi.c index 9ddac9d..65a626f 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -2190,12 +2190,16 @@ void ftdi_eeprom_initdefaults(struct ftdi_context *ftdi) eeprom->vendor_id = 0x0403; eeprom->use_serial = USE_SERIAL_NUM; - if((ftdi->type= TYPE_AM) || (ftdi->type= TYPE_BM) ||(ftdi->type= TYPE_R)) + if((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM) || + (ftdi->type == TYPE_R)) eeprom->product_id = 0x6001; else eeprom->product_id = 0x6010; switch (ftdi->type) { + case TYPE_2232C: + eeprom->release = 0x500; + break; case TYPE_2232H: eeprom->release = 0x200; break; @@ -2257,6 +2261,7 @@ void ftdi_eeprom_free(struct ftdi_context *ftdi) \retval -3: Invalid cbus function setting \retval -4: Chip doesn't support invert \retval -5: Chip doesn't support high current drive + \retval -6: No connected EEPROM or EEPROM Type unknown */ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) { @@ -2274,6 +2279,9 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) eeprom= ftdi->eeprom; + if(eeprom->chip == -1) + ftdi_error_return(-5,"No connected EEPROM or EEPROM Type unknown"); + if (eeprom->manufacturer != NULL) manufacturer_size = strlen(eeprom->manufacturer); if (eeprom->product != NULL) @@ -2508,7 +2516,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, if (ftdi == NULL) ftdi_error_return(-1,"No context"); if (ftdi->eeprom == NULL) - ftdi_error_return(-1,"No eeprom"); + ftdi_error_return(-1,"No eeprom structure"); eeprom_size = ftdi->eeprom->size; if(ftdi->type == TYPE_R) @@ -2652,14 +2660,15 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, else if ((ftdi->type == TYPE_AM) || (ftdi->type == TYPE_BM)) { - eeprom->chip = buf[14]; + eeprom->chip = -1; } else if(ftdi->type == TYPE_2232C) { - eeprom->chip = buf[14]; + eeprom->chip = buf[0x14]; } else if(ftdi->type == TYPE_R) { + eeprom->chip = buf[0x16]; // Addr 0B: Invert data lines // Works only on FT232R, not FT245R, but no way to distinguish eeprom->invert = buf[0x0B]; @@ -2674,6 +2683,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, } else if ((ftdi->type == TYPE_2232H) ||(ftdi->type == TYPE_4232H)) { + eeprom->chip = buf[0x18]; eeprom->group0_drive = buf[0x0c] & DRIVE_16MA; eeprom->group0_schmitt = buf[0x0c] & IS_SCHMITT; eeprom->group0_slew = buf[0x0c] & SLOW_SLEW; @@ -2698,7 +2708,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, if(eeprom->self_powered) fprintf(stdout, "Self-Powered%s", (eeprom->remote_wakeup)?", USB Remote Wake Up\n":"\n"); else - fprintf(stdout, "Bus Powered: %3d mA%s", eeprom->max_power*2, + fprintf(stdout, "Bus Powered: %3d mA%s", eeprom->max_power * 2, (eeprom->remote_wakeup)?" USB Remote Wake Up\n":"\n"); if(eeprom->manufacturer) fprintf(stdout, "Manufacturer: %s\n",eeprom->manufacturer); @@ -2707,6 +2717,10 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, if(eeprom->serial) fprintf(stdout, "Serial: %s\n",eeprom->serial); fprintf(stdout, "Checksum : %04x\n", checksum); + if (ftdi->type == TYPE_R) + fprintf(stdout, "Internal EEPROM\n"); + else if (eeprom->chip >= 0x46) + fprintf(stdout, "Attached EEPROM: 93x%02x\n", eeprom->chip); if(eeprom->suspend_dbus7) fprintf(stdout, "Suspend on DBUS7\n"); if(eeprom->suspend_pull_downs) @@ -2936,15 +2950,61 @@ int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) \retval 0: all fine \retval -1: erase failed \retval -2: USB device unavailable + \retval -3: Writing magic failed + \retval -4: Read EEPROM failed + \retval -5: Unexpected EEPROM value */ +#define MAGIC 0x55aa int ftdi_erase_eeprom(struct ftdi_context *ftdi) { + unsigned short eeprom_value; if (ftdi == NULL || ftdi->usb_dev == NULL) ftdi_error_return(-2, "USB device unavailable"); - if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, SIO_ERASE_EEPROM_REQUEST, 0, 0, NULL, 0, ftdi->usb_write_timeout) < 0) + if(ftdi->type == TYPE_R) + { + ftdi->eeprom->chip = 0; + return 0; + } + + if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, SIO_ERASE_EEPROM_REQUEST, + 0, 0, NULL, 0, ftdi->usb_write_timeout) < 0) ftdi_error_return(-1, "unable to erase eeprom"); + + /* detect chip type by writing 0x55AA as magic at word position 0xc0 + Chip is 93x46 if magic is read at word position 0x00, as wraparound happens around 0x40 + Chip is 93x56 if magic is read at word position 0x40, as wraparound happens around 0x80 + Chip is 93x66 if magic is only read at word position 0xc0*/ + if( ftdi_write_eeprom_location(ftdi, 0xc0, MAGIC)) + ftdi_error_return(-3, "Writing magic failed"); + if (ftdi_read_eeprom_location( ftdi, 0x00, &eeprom_value)) + ftdi_error_return(-4, "Reading failed failed"); + if(eeprom_value == MAGIC) + { + ftdi->eeprom->chip = 0x46; + } + else + { + if (ftdi_read_eeprom_location( ftdi, 0x40, &eeprom_value)) + ftdi_error_return(-4, "Reading failed failed"); + if(eeprom_value == MAGIC) + ftdi->eeprom->chip = 0x56; + else + { + if (ftdi_read_eeprom_location( ftdi, 0xc0, &eeprom_value)) + ftdi_error_return(-4, "Reading failed failed"); + if(eeprom_value == MAGIC) + ftdi->eeprom->chip = 0x66; + else + { + ftdi->eeprom->chip = -1; + } + } + } + if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, SIO_ERASE_EEPROM_REQUEST, + 0, 0, NULL, 0, ftdi->usb_write_timeout) < 0) + ftdi_error_return(-1, "unable to erase eeprom"); return 0; }