-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Am 10.06.2013 13:33, schrieb Ori Idan:
> I still did not find a solution how to program EEPROM on FT4232 I am using
> Ubuntu 12.10 with libftdi1 0.20
Having had the same problem I have modified the eeprom example (see attached
program). For my setting it is sufficient
to read and write binary data, since I only have to set a known configuration.
To get the binary data I used the windows configuration program from ftdichip
(http://www.ftdichip.com/Support/Utilities.htm#FT_Prog) to program the eeprom
and read it using eeprom-set on linux.
Hope that helps
Greetings
Andreas
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iEYEARECAAYFAlHAGO8ACgkQDVaV4kk68F8s9gCgrOo4ze0R0EKWTSQELF3/CckV
TD0AoIAzbaRIJxDZHhZtOtfBDweDN5Sz
=GAB9
-----END PGP SIGNATURE-----
--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to [email protected]
/*
* read/verify/erase/write eeprom
* only binary data files (raw data) supported
*
* based on
* LIBFTDI EEPROM access example
*
* This program is distributed under the GPL, version 2
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>
#include <ftdi.h>
#include <libusb.h>
#define CMD_NONE 0
#define CMD_READ 1
#define CMD_WRITE 2
#define CMD_VERIFY 3
#define CMD_ERASE 4
#define CMD_LIST 5
#define CMD_UNDEF 99
#define MAX_EEPROM_SIZE 256
int erase_eeprom(struct ftdi_context *ftdi)
{
int f;
int value;
f = ftdi_erase_eeprom(ftdi); /* needed to determine EEPROM chip type */
if (f < 0)
{
fprintf(stderr, "Erase failed: %s",
ftdi_get_error_string(ftdi));
return -2;
}
if (ftdi_get_eeprom_value(ftdi, CHIP_TYPE, & value) <0)
{
fprintf(stderr, "ftdi_get_eeprom_value: %d (%s)\n",
f, ftdi_get_error_string(ftdi));
}
if (value == -1)
fprintf(stderr, "No EEPROM\n");
else if (value == 0)
fprintf(stderr, "Internal EEPROM\n");
else
fprintf(stderr, "Found 93x%02x\n", value);
return value;
}
int verify_eeprom(struct ftdi_context *ftdi, unsigned char *data, int size)
{
int ret;
int eepromSize;
int i;
unsigned char *eepromData;
ret = ftdi_read_eeprom(ftdi);
if (ret < 0)
{
fprintf(stderr, "Unable to read eeprom: (%s)\n", ftdi_get_error_string(ftdi));
return -1;
}
ret = ftdi_get_eeprom_value(ftdi, CHIP_SIZE, &eepromSize);
if (ret < 0 || eepromSize != size)
{
fprintf(stderr, "verify failed; size mismatch\n");
return -1;
}
eepromData = malloc(eepromSize);
if (eepromData == 0)
{
fprintf(stderr, "can't allocate buffer\n");
return -1;
}
ftdi_get_eeprom_buf(ftdi, eepromData, eepromSize);
for (i = 0; i < size; i++)
{
if (eepromData[i] != data[i])
{
fprintf(stderr, "verify failed; first data mismatch at %d\n", i);
return -1;
}
}
return 0;
}
int read_eeprom(struct ftdi_context *ftdi, char *filename)
{
int ret;
int eepromSize;
int fh;
unsigned char *eepromData;
ret = ftdi_read_eeprom(ftdi);
if (ret < 0)
{
fprintf(stderr, "Unable to read eeprom: (%s)\n", ftdi_get_error_string(ftdi));
return -1;
}
ret = ftdi_get_eeprom_value(ftdi, CHIP_SIZE, &eepromSize);
if (ret < 0 || eepromSize == 0 || eepromSize > MAX_EEPROM_SIZE)
{
fprintf(stderr, "eeprom read failed\n");
return -1;
}
eepromData = malloc(eepromSize);
if (eepromData == 0)
{
fprintf(stderr, "can't allocate buffer\n");
return -1;
}
ftdi_get_eeprom_buf(ftdi, eepromData, eepromSize);
fh = creat(filename, 0666);
if (fh < 0)
{
fprintf(stderr, "can't open file %s to write\n", filename);
return -1;
}
ret = write(fh, eepromData, eepromSize);
if (ret != eepromSize)
{
fprintf(stderr, "error while writing data to file %s\n", filename);
close(fh);
return -1;
}
close(fh);
return 0;
}
int write_eeprom(struct ftdi_context *ftdi, unsigned char *data, int size)
{
erase_eeprom(ftdi);
ftdi_eeprom_initdefaults(ftdi, "", "", "");
ftdi_eeprom_build(ftdi);
ftdi_set_eeprom_buf(ftdi, data, size);
if (ftdi_write_eeprom(ftdi) < 0)
{
fprintf(stderr, "Failed to write eeprom :%s \n",
ftdi_get_error_string(ftdi));
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
struct ftdi_context *ftdi;
struct ftdi_device_list *devlist, *curdev;
int res, i;
int vid = 0;
int pid = 0;
int index = -1;
int all = 0;
int do_reset = 0;
int cmd = CMD_NONE;
int retval = 0;
char *filename = 0;
unsigned char fileData[MAX_EEPROM_SIZE];
int fileDataSize = 0;
if ((ftdi = ftdi_new()) == 0)
{
fprintf(stderr, "Failed to allocate ftdi structure :%s \n",
ftdi_get_error_string(ftdi));
return EXIT_FAILURE;
}
while ((i = getopt(argc, argv, "ewrvlaRP:V:I:")) != -1)
{
switch (i)
{
case 'e':
if (cmd != CMD_NONE)
cmd = CMD_UNDEF;
else
cmd = CMD_ERASE;
break;
case 'v':
if (cmd != CMD_NONE)
cmd = CMD_UNDEF;
else
cmd = CMD_VERIFY;
break;
case 'r':
if (cmd != CMD_NONE)
cmd = CMD_UNDEF;
else
cmd = CMD_READ;
break;
case 'w':
if (cmd != CMD_NONE)
cmd = CMD_UNDEF;
else
cmd = CMD_WRITE;
break;
case 'l':
if (cmd != CMD_NONE)
cmd = CMD_UNDEF;
else
cmd = CMD_LIST;
break;
case 'R':
do_reset = 1;
break;
case 'V':
vid = strtoul(optarg, NULL, 0);
break;
case 'P':
pid = strtoul(optarg, NULL, 0);
break;
case 'I':
index = strtoul(optarg, NULL, 0);
break;
case 'a':
all = 1;
break;
default:
fprintf(stderr, "usage: %s [options] [filename]\n", *argv);
fprintf(stderr, "\t-w write\n");
fprintf(stderr, "\t-e erase\n");
fprintf(stderr, "\t-r read\n");
fprintf(stderr, "\t-v verify\n");
fprintf(stderr, "\t-R reset\n");
fprintf(stderr, "\t-l list ftdi devices\n");
fprintf(stderr, "\t-P <number> Search for device with PID == number\n");
fprintf(stderr, "\t-V <number> Search for device with VID == number\n");
fprintf(stderr, "\t-I <number> Use device with index == number\n");
fprintf(stderr, "\t-a Use all connected devices (only useable with cmd -e, -w, -v\n");
retval = -1;
goto do_deinit;
}
}
if (cmd == CMD_NONE || cmd == CMD_UNDEF)
{
fprintf(stderr, "One and only one command (-v, -e, -r, -w, -l) must be supplied.\n");
retval = EXIT_FAILURE;
goto do_deinit;
}
if (cmd == CMD_READ || cmd == CMD_WRITE || cmd == CMD_VERIFY)
{
if (optind >= argc)
{
fprintf(stderr, "Missing filename.\n");
retval = EXIT_FAILURE;
goto do_deinit;
}
filename = argv[optind];
if (cmd == CMD_WRITE || cmd == CMD_VERIFY)
{
int fh;
fh = open(filename, O_RDONLY);
if (fh < 0)
{
fprintf(stderr, "can't open file %s to read\n", filename);
retval = EXIT_FAILURE;
goto do_deinit;
}
fileDataSize = read(fh, fileData, sizeof(fileData));
if (fileDataSize <= 0)
{
fprintf(stderr, "error while reading data from file %s\n", filename);
close(fh);
retval = EXIT_FAILURE;
goto do_deinit;
}
close(fh);
}
}
if ((res = ftdi_usb_find_all(ftdi, &devlist, vid, pid)) < 0)
{
fprintf(stderr, "No FTDI found\n");
retval = EXIT_FAILURE;
goto do_deinit;
}
else if (res >= 1)
{
int f;
i = 0;
if (res > 1 && cmd != CMD_LIST)
{
if (!all && index < 0 && cmd != CMD_READ)
{
fprintf(stderr, "Found %d devices and neither -a nor -I given!\n", res);
retval = EXIT_FAILURE;
goto do_deinit;
}
if (index < 0 && cmd == CMD_READ)
{
fprintf(stderr, "Found %d devices and -I not given!\n", res);
retval = EXIT_FAILURE;
goto do_deinit;
}
} else if (index < 0)
index = 0;
for (curdev = devlist; curdev != NULL; i++)
{
if (cmd == CMD_LIST)
{
char manufacturer[128], description[128];
int ret;
printf("Checking device: %d ", i);
if ((ret = ftdi_usb_get_strings(ftdi, curdev->dev, manufacturer, 128, description, 128, NULL, 0)) < 0)
{
fprintf(stderr, "ftdi_usb_get_strings failed: %d (%s)\n", ret, ftdi_get_error_string(ftdi));
retval = EXIT_FAILURE;
goto do_deinit;
}
printf("Manufacturer/Description: %s / %s\n", manufacturer, description);
}
else if (all || i == index)
{
f = ftdi_usb_open_dev(ftdi, curdev->dev);
if (f<0)
{
fprintf(stderr, "Unable to open device %d: (%s)\n",
i, ftdi_get_error_string(ftdi));
}
fprintf(stderr, "Using device %d: ", i);
if (cmd == CMD_ERASE)
{
int ret;
fprintf(stderr, "erasing eeprom\n");
ret = erase_eeprom(ftdi);
if (ret < 0)
retval = ret;
else
fprintf(stderr, "erase OK\n");
do_reset = 1;
}
if (cmd == CMD_VERIFY)
{
int ret;
fprintf(stderr, "verifying eeprom ... ");
ret = verify_eeprom(ftdi, fileData, fileDataSize);
if (ret < 0)
{
retval = ret;
} else
fprintf(stderr, "verify OK\n");
}
if (cmd == CMD_READ)
{
int ret;
fprintf(stderr, "reading eeprom ... ");
ret = read_eeprom(ftdi, filename);
if (ret < 0)
{
retval = ret;
} else
{
fprintf(stderr, " OK\n");
}
}
if (cmd == CMD_WRITE)
{
int ret;
fprintf(stderr, "checking eeprom ... ");
ret = verify_eeprom(ftdi, fileData, fileDataSize);
if (ret < 0)
{
fprintf(stderr, " writing ... ");
ret = write_eeprom(ftdi, fileData, fileDataSize);
if (ret < 0)
retval = ret;
else
{
fprintf(stderr, "OK, verifying ... ");
ret = verify_eeprom(ftdi, fileData, fileDataSize);
if (ret < 0)
retval = ret;
else
{
fprintf(stderr, "OK\n");
}
}
do_reset = 1;
} else
{
fprintf(stderr, "verify OK, no need to write\n");
}
}
libusb_device *usb_dev = libusb_get_device(ftdi->usb_dev);
ftdi_usb_close(ftdi);
if (cmd != CMD_LIST)
{
int ret;
libusb_device_handle *dev_handle;
ret = libusb_open(usb_dev, &dev_handle);
if (ret != 0)
{
fprintf(stderr, " failed: libusb error code %d \n", ret);
}
else
{
fprintf(stderr, "reattaching serial driver ... ");
ret = libusb_attach_kernel_driver(dev_handle, 0);
if (ret != 0)
{
retval = EXIT_FAILURE;
fprintf(stderr, " failed: libusb error code %d \n", ret);
} else
{
fprintf(stderr, " OK\n");
}
if (do_reset)
{
int ret;
fprintf(stderr, "resetting device ... ");
ret = libusb_reset_device(dev_handle);
if (ret != 0)
{
retval = EXIT_FAILURE;
fprintf(stderr, " failed\n");
} else
{
fprintf(stderr, " OK\n");
}
}
libusb_close(dev_handle);
}
}
}
curdev = curdev->next;
}
}
else
{
fprintf(stderr, "No devices found\n");
}
ftdi_list_free(&devlist);
do_deinit:
ftdi_free(ftdi);
return retval;
}