From: Uwe Bonnes Date: Tue, 14 Sep 2010 12:46:02 +0000 (+0200) Subject: Provide internal eeprom structure buffer with internal byte buffer Purge external... X-Git-Tag: v1.0rc1~133^2~66 X-Git-Url: http://developer.intra2net.com/git/?p=libftdi;a=commitdiff_plain;h=a35aa9bdfbb149efe72c32727a0ebfe3585465f8 Provide internal eeprom structure buffer with internal byte buffer Purge external eeprom structure buffer and eeprom read/write byte buffer from API --- diff --git a/bindings/ftdi.i b/bindings/ftdi.i index 1fc2a59..6e56cfe 100644 --- a/bindings/ftdi.i +++ b/bindings/ftdi.i @@ -39,12 +39,12 @@ extern "C" { %clear unsigned short *status; %apply char *OUTPUT { unsigned char *output }; - int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output); + int ftdi_eeprom_build(struct ftdi_context *ftdi); %clear unsigned char *output; %apply char *OUTPUT { unsigned char *eeprom }; - int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); - int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); + int ftdi_read_eeprom(struct ftdi_context *ftdi); + int ftdi_write_eeprom(struct ftdi_context *ftdi); %clear unsigned char *eeprom; %apply int *OUTPUT { unsigned int *chipid }; diff --git a/examples/eeprom.c b/examples/eeprom.c index 756bb04..609ab99 100644 --- a/examples/eeprom.c +++ b/examples/eeprom.c @@ -14,9 +14,7 @@ int main(int argc, char **argv) { struct ftdi_context *ftdi; - struct ftdi_eeprom eeprom; - unsigned char buf[2048]; - int size; + unsigned char *buf; int f, i, j; int vid = 0x0403; int pid = 0x6010; @@ -25,10 +23,12 @@ int main(int argc, char **argv) int erase = 0; int use_defaults = 0; int large_chip = 0; + int size; if ((ftdi = ftdi_new()) == 0) { - fprintf(stderr,"Failed to allocate ftdi structure\n"); + fprintf(stderr, "Failed to allocate ftdi structure :%s \n", + ftdi_get_error_string(ftdi)); return EXIT_FAILURE; } @@ -72,13 +72,6 @@ int main(int argc, char **argv) } } - // Init - if (ftdi_init(ftdi) < 0) - { - fprintf(stderr, "ftdi_init failed\n"); - return EXIT_FAILURE; - } - // Select first interface ftdi_set_interface(ftdi, INTERFACE_ANY); @@ -100,7 +93,6 @@ int main(int argc, char **argv) if (erase) { - ftdi_eeprom_setsize(ftdi, &eeprom, 2048); f = ftdi_erase_eeprom(ftdi); if (f < 0) { @@ -117,22 +109,14 @@ int main(int argc, char **argv) return 0; } - size = 2048; - memset(buf,0, size); - ftdi->eeprom = &eeprom; if(use_defaults) { ftdi_eeprom_initdefaults(ftdi); ftdi->eeprom->manufacturer="IKDA"; ftdi->eeprom->product="CPS-CONN"; ftdi->eeprom->serial="0001"; - ftdi->eeprom->chip= large_chip; - ftdi->eeprom->cbus_function[0]= CBUS_BB_RD; - ftdi->eeprom->cbus_function[1]= CBUS_CLK48; - ftdi->eeprom->cbus_function[2]= CBUS_IOMODE; - ftdi->eeprom->cbus_function[3]= CBUS_BB; - ftdi->eeprom->cbus_function[4]= CBUS_CLK6; - f=(ftdi_eeprom_build(ftdi, buf)); + ftdi->eeprom->chip= (large_chip)?0x66:0; + f=(ftdi_eeprom_build(ftdi)); if (f < 0) { fprintf(stderr, "ftdi_eeprom_build: %d (%s)\n", @@ -142,7 +126,7 @@ int main(int argc, char **argv) } else { - f = ftdi_read_eeprom(ftdi, buf); + f = ftdi_read_eeprom(ftdi); if (f < 0) { fprintf(stderr, "ftdi_read_eeprom: %d (%s)\n", @@ -151,7 +135,12 @@ int main(int argc, char **argv) } } fprintf(stderr, "Chip type %d ftdi_eeprom_size: %d\n", ftdi->type, ftdi->eeprom->size); - for(i=0; i < ftdi->eeprom->size; i += 16) + buf = ftdi->eeprom->buf; + if (ftdi->type == TYPE_R) + size = 0xa0; + else + size = ftdi->eeprom->size; + for(i=0; i < size; i += 16) { fprintf(stdout,"0x%03x:", i); @@ -169,7 +158,7 @@ int main(int argc, char **argv) fprintf(stdout,"\n"); } - f = ftdi_eeprom_decode(ftdi,buf, size, 1); + f = ftdi_eeprom_decode(ftdi, 1); { fprintf(stderr, "ftdi_eeprom_decode: %d (%s)\n", f, ftdi_get_error_string(ftdi)); diff --git a/ftdipp/ftdi.cpp b/ftdipp/ftdi.cpp index de0735d..ed1d807 100644 --- a/ftdipp/ftdi.cpp +++ b/ftdipp/ftdi.cpp @@ -398,11 +398,6 @@ void Eeprom::init_defaults() return ftdi_eeprom_initdefaults(d->context); } -void Eeprom::set_size(int size) -{ - return ftdi_eeprom_setsize(d->context, &d->eeprom, size); -} - int Eeprom::chip_id(unsigned int *chipid) { return ftdi_read_chipid(d->context, chipid); @@ -410,17 +405,17 @@ int Eeprom::chip_id(unsigned int *chipid) int Eeprom::build(unsigned char *output) { - return ftdi_eeprom_build(d->context, output); + return ftdi_eeprom_build(d->context); } int Eeprom::read(unsigned char *eeprom) { - return ftdi_read_eeprom(d->context, eeprom); + return ftdi_read_eeprom(d->context); } int Eeprom::write(unsigned char *eeprom) { - return ftdi_write_eeprom(d->context, eeprom); + return ftdi_write_eeprom(d->context); } int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val) diff --git a/src/ftdi.c b/src/ftdi.c index 67fd259..63e2a36 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -73,11 +73,13 @@ 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 \remark This should be called before all functions */ int ftdi_init(struct ftdi_context *ftdi) { + struct ftdi_eeprom* eeprom = (struct ftdi_eeprom *)malloc(sizeof(struct ftdi_eeprom)); ftdi->usb_ctx = NULL; ftdi->usb_dev = NULL; ftdi->usb_read_timeout = 5000; @@ -101,7 +103,9 @@ int ftdi_init(struct ftdi_context *ftdi) ftdi->error_str = NULL; - ftdi->eeprom = NULL; + if (eeprom == 0) + ftdi_error_return(-2, "Can't malloc struct ftdi_eeprom"); + ftdi->eeprom = eeprom; /* All fine. Now allocate the readbuffer */ return ftdi_read_data_set_chunksize(ftdi, 4096); @@ -192,6 +196,12 @@ void ftdi_deinit(struct ftdi_context *ftdi) free(ftdi->readbuffer); ftdi->readbuffer = NULL; } + + if (ftdi->eeprom != NULL) + { + free(ftdi->eeprom); + ftdi->eeprom = NULL; + } libusb_exit(ftdi->usb_ctx); } @@ -2153,30 +2163,12 @@ int ftdi_set_error_char(struct ftdi_context *ftdi, } /** - Set the eeprom size - - \param ftdi pointer to ftdi_context - \param eeprom Pointer to ftdi_eeprom - \param size - -*/ -void ftdi_eeprom_setsize(struct ftdi_context *ftdi, struct ftdi_eeprom *eeprom, int size) -{ - if (ftdi == NULL) - return; - - ftdi->eeprom = eeprom; - ftdi->eeprom->size=size; -} - -/** Init eeprom with default values. + \param ftdi pointer to ftdi_context - \param eeprom Pointer to ftdi_eeprom */ void ftdi_eeprom_initdefaults(struct ftdi_context *ftdi) { - int i; struct ftdi_eeprom *eeprom; if (ftdi == NULL) @@ -2222,7 +2214,7 @@ void ftdi_eeprom_initdefaults(struct ftdi_context *ftdi) /** Frees allocated memory in eeprom. - \param eeprom Pointer to ftdi_eeprom + \param ftdi pointer to ftdi_context */ void ftdi_eeprom_free(struct ftdi_context *ftdi) { @@ -2248,12 +2240,10 @@ void ftdi_eeprom_free(struct ftdi_context *ftdi) } /** - Build binary output from ftdi_eeprom structure. + Build binary buffer from ftdi_eeprom structure. Output is suitable for ftdi_write_eeprom(). - \note This function doesn't handle FT2232x devices. Only FT232x. - \param eeprom Pointer to ftdi_eeprom - \param output Buffer of 128 bytes to store eeprom image to + \param ftdi pointer to ftdi_context \retval >0: free eeprom size \retval -1: eeprom size (128 bytes) exceeded by custom strings @@ -2263,13 +2253,14 @@ void ftdi_eeprom_free(struct ftdi_context *ftdi) \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) +int ftdi_eeprom_build(struct ftdi_context *ftdi) { unsigned char i, j, k; unsigned short checksum, value; unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0; int size_check; struct ftdi_eeprom *eeprom; + unsigned char * output; if (ftdi == NULL) ftdi_error_return(-2,"No context"); @@ -2277,6 +2268,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) ftdi_error_return(-2,"No eeprom structure"); eeprom= ftdi->eeprom; + output = eeprom->buf; if(eeprom->chip == -1) ftdi_error_return(-5,"No connected EEPROM or EEPROM Type unknown"); @@ -2320,7 +2312,7 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) return (-1); // empty eeprom - memset (output, 0, eeprom->size); + memset (ftdi->eeprom->buf, 0, FTDI_MAX_EEPROM_SIZE); // Bytes and Bits set for all Types @@ -2632,23 +2624,23 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output) /** Decode binary EEPROM image into an ftdi_eeprom structure. - \param eeprom Pointer to ftdi_eeprom which will be filled in. - \param buf Buffer of \a size bytes of raw eeprom data - \param size size size of eeprom data in bytes - + \param ftdi pointer to ftdi_context + \param verbose Decode EEPROM on stdout + \retval 0: all fine \retval -1: something went wrong FIXME: How to pass size? How to handle size field in ftdi_eeprom? FIXME: Strings are malloc'ed here and should be freed somewhere */ -int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, int verbose) +int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) { unsigned char i, j; unsigned short checksum, eeprom_checksum, value; unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0; int eeprom_size; struct ftdi_eeprom *eeprom; + unsigned char *buf = ftdi->eeprom->buf; int release; if (ftdi == NULL) @@ -2656,10 +2648,8 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *buf, int size, if (ftdi->eeprom == NULL) ftdi_error_return(-1,"No eeprom structure"); - eeprom_size = ftdi->eeprom->size; - if(ftdi->type == TYPE_R) - eeprom_size = 0x80; eeprom = ftdi->eeprom; + eeprom_size = eeprom->size; // Addr 02: Vendor ID eeprom->vendor_id = buf[0x02] + (buf[0x03] << 8); @@ -2966,34 +2956,37 @@ int ftdi_read_eeprom_location (struct ftdi_context *ftdi, int eeprom_addr, unsig Read eeprom \param ftdi pointer to ftdi_context - \param eeprom Pointer to store eeprom into \retval 0: all fine \retval -1: read failed \retval -2: USB device unavailable */ -int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) +int ftdi_read_eeprom(struct ftdi_context *ftdi) { int i; + unsigned char *buf; if (ftdi == NULL || ftdi->usb_dev == NULL) ftdi_error_return(-2, "USB device unavailable"); + buf = ftdi->eeprom->buf; for (i = 0; i < FTDI_MAX_EEPROM_SIZE/2; i++) { - if (libusb_control_transfer(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, SIO_READ_EEPROM_REQUEST, 0, i, eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2) + if (libusb_control_transfer( + ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE,SIO_READ_EEPROM_REQUEST, 0, i, + buf+(i*2), 2, ftdi->usb_read_timeout) != 2) ftdi_error_return(-1, "reading eeprom failed"); } if (ftdi->type == TYPE_R) - ftdi->eeprom->size = 0xa0; + ftdi->eeprom->size = 0x80; /* Guesses size of eeprom by comparing halves - will not work with blank eeprom */ - else if (strrchr((const char *)eeprom, 0xff) == ((const char *)eeprom +FTDI_MAX_EEPROM_SIZE -1)) + else if (strrchr((const char *)buf, 0xff) == ((const char *)buf +FTDI_MAX_EEPROM_SIZE -1)) ftdi->eeprom->size = -1; - else if(memcmp(eeprom,&eeprom[0x80],0x80) == 0) + else if(memcmp(buf,&buf[0x80],0x80) == 0) ftdi->eeprom->size = 0x80; - else if(memcmp(eeprom,&eeprom[0x40],0x40) == 0) + else if(memcmp(buf,&buf[0x40],0x40) == 0) ftdi->eeprom->size = 0x40; else ftdi->eeprom->size = 0x100; @@ -3079,19 +3072,20 @@ int ftdi_write_eeprom_location(struct ftdi_context *ftdi, int eeprom_addr, unsig Write eeprom \param ftdi pointer to ftdi_context - \param eeprom Pointer to read eeprom from - + \retval 0: all fine \retval -1: read failed \retval -2: USB device unavailable */ -int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) +int ftdi_write_eeprom(struct ftdi_context *ftdi) { unsigned short usb_val, status; int i, ret; + unsigned char *eeprom; if (ftdi == NULL || ftdi->usb_dev == NULL) ftdi_error_return(-2, "USB device unavailable"); + eeprom = ftdi->eeprom->buf; /* These commands were traced while running MProg */ if ((ret = ftdi_usb_reset(ftdi)) != 0) diff --git a/src/ftdi.h b/src/ftdi.h index d42c8c2..ec561bf 100644 --- a/src/ftdi.h +++ b/src/ftdi.h @@ -252,6 +252,7 @@ struct ftdi_eeprom int size; /* EEPROM Type 46 for 93xx46, 56 for 93xx56 and 66 for 93xx66*/ int chip; + unsigned char buf[FTDI_MAX_EEPROM_SIZE]; }; /** @@ -468,20 +469,15 @@ extern "C" int ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable); int ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable); - /* set eeprom size */ - void ftdi_eeprom_setsize(struct ftdi_context *ftdi, struct ftdi_eeprom *eeprom, int size); - /* init and build eeprom from ftdi_eeprom structure */ void ftdi_eeprom_initdefaults(struct ftdi_context *ftdi); void ftdi_eeprom_free(struct ftdi_context *ftdi); - int ftdi_eeprom_build(struct ftdi_context *ftdi, unsigned char *output); - int ftdi_eeprom_decode(struct ftdi_context *ftdi, unsigned char *output, int size, int verbose); + int ftdi_eeprom_build(struct ftdi_context *ftdi); + int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose); - /* "eeprom" needs to be valid 128 byte eeprom (generated by the eeprom generator) - the checksum of the eeprom is valided */ - int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); + int ftdi_read_eeprom(struct ftdi_context *ftdi); int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid); - int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom); + int ftdi_write_eeprom(struct ftdi_context *ftdi); int ftdi_erase_eeprom(struct ftdi_context *ftdi); int ftdi_read_eeprom_location (struct ftdi_context *ftdi, int eeprom_addr, unsigned short *eeprom_val);