#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
#include <confuse.h>
#include <libusb.h>
return -1;
}
+static int parse_chtype(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result)
+{
+ static const struct
+ {
+ char* key;
+ int opt;
+ } options[] =
+ {
+ { "UART", CHANNEL_IS_UART },
+ { "FIFO", CHANNEL_IS_FIFO },
+ { "OPTO", CHANNEL_IS_OPTO },
+ { "CPU", CHANNEL_IS_CPU },
+ { "FT1284", CHANNEL_IS_FT1284}
+ };
+
+ int i;
+ for (i=0; i<sizeof(options)/sizeof(*options); i++)
+ {
+ if (!(strcmp(options[i].key, value)))
+ {
+ *(int *)result = options[i].opt;
+ return 0;
+ }
+ }
+
+ cfg_error(cfg, "Invalid %s option '%s'", cfg_opt_name(opt), value);
+ return -1;
+}
+
/**
* @brief Set eeprom value
*
fprintf(stderr, " i:<vendor>:<product>:<index>\n");
fprintf(stderr, " s:<vendor>:<product>:<serial>\n");
fprintf(stderr, "--read-eeprom Read eeprom and write to -filename- from config-file\n");
+ fprintf(stderr, "--build-eeprom Build eeprom image\n");
fprintf(stderr, "--erase-eeprom Erase eeprom\n");
fprintf(stderr, "--flash-eeprom Flash eeprom\n");
}
CFG_BOOL("invert_dsr", cfg_false, 0),
CFG_BOOL("invert_dcd", cfg_false, 0),
CFG_BOOL("invert_ri", cfg_false, 0),
+ CFG_INT_CB("cha_type", -1, 0, parse_chtype),
+ CFG_INT_CB("chb_type", -1, 0, parse_chtype),
+ CFG_BOOL("cha_vcp", cfg_true, 0),
+ CFG_BOOL("chb_vcp", cfg_true, 0),
+ CFG_BOOL("chc_vcp", cfg_true, 0),
+ CFG_BOOL("chd_vcp", cfg_true, 0),
+ CFG_BOOL("cha_rs485", cfg_false, 0),
+ CFG_BOOL("chb_rs485", cfg_false, 0),
+ CFG_BOOL("chc_rs485", cfg_false, 0),
+ CFG_BOOL("chd_rs485", cfg_false, 0),
+ CFG_FUNC("include", &cfg_include),
+ CFG_INT("user_data_addr", 0x18, 0),
+ CFG_STR("user_data_file", "", 0),
CFG_END()
};
cfg_t *cfg;
enum {
COMMAND_READ = 1,
COMMAND_ERASE,
- COMMAND_FLASH
+ COMMAND_FLASH,
+ COMMAND_BUILD
} command = 0;
const char *cfg_filename = NULL;
const char *device_description = NULL;
+ const char *user_data_file = NULL;
+ char *user_data_buffer = NULL;
const int max_eeprom_size = 256;
int my_eeprom_size = 0;
{
command = COMMAND_FLASH;
}
+ else if (!strcmp(argv[i], "--build-eeprom"))
+ {
+ command = COMMAND_BUILD;
+ }
else
{
usage(argv[0]);
}
if (filename != NULL && strlen(filename) > 0)
{
-
FILE *fp = fopen (filename, "wb");
- fwrite (eeprom_buf, 1, my_eeprom_size, fp);
- fclose (fp);
+
+ if(fp)
+ {
+ fwrite(eeprom_buf, 1, my_eeprom_size, fp);
+ fclose(fp);
+ }
+ else
+ fprintf(stderr, "Could not open output file %s: %s\n", filename, strerror(errno));
}
else
{
if (cfg_getbool(cfg, "invert_ri")) invert |= INVERT_RI;
eeprom_set_value(ftdi, INVERT, invert);
- eeprom_set_value(ftdi, CHANNEL_A_DRIVER, DRIVER_VCP);
- eeprom_set_value(ftdi, CHANNEL_B_DRIVER, DRIVER_VCP);
- eeprom_set_value(ftdi, CHANNEL_C_DRIVER, DRIVER_VCP);
- eeprom_set_value(ftdi, CHANNEL_D_DRIVER, DRIVER_VCP);
- eeprom_set_value(ftdi, CHANNEL_A_RS485, 0);
- eeprom_set_value(ftdi, CHANNEL_B_RS485, 0);
- eeprom_set_value(ftdi, CHANNEL_C_RS485, 0);
- eeprom_set_value(ftdi, CHANNEL_D_RS485, 0);
+ if (cfg_getint(cfg, "cha_type") != -1)
+ eeprom_set_value(ftdi, CHANNEL_A_TYPE, cfg_getint(cfg, "cha_type"));
+ if (cfg_getint(cfg, "chb_type") != -1)
+ eeprom_set_value(ftdi, CHANNEL_B_TYPE, cfg_getint(cfg, "chb_type"));
+
+ eeprom_set_value(ftdi, CHANNEL_A_DRIVER,
+ cfg_getbool(cfg, "cha_vcp") ? DRIVER_VCP : 0);
+ eeprom_set_value(ftdi, CHANNEL_B_DRIVER,
+ cfg_getbool(cfg, "chb_vcp") ? DRIVER_VCP : 0);
+ eeprom_set_value(ftdi, CHANNEL_C_DRIVER,
+ cfg_getbool(cfg, "chc_vcp") ? DRIVER_VCP : 0);
+ eeprom_set_value(ftdi, CHANNEL_D_DRIVER,
+ cfg_getbool(cfg, "chd_vcp") ? DRIVER_VCP : 0);
+
+ eeprom_set_value(ftdi, CHANNEL_A_RS485, cfg_getbool(cfg, "cha_rs485"));
+ eeprom_set_value(ftdi, CHANNEL_B_RS485, cfg_getbool(cfg, "chb_rs485"));
+ eeprom_set_value(ftdi, CHANNEL_C_RS485, cfg_getbool(cfg, "chc_rs485"));
+ eeprom_set_value(ftdi, CHANNEL_D_RS485, cfg_getbool(cfg, "chd_rs485"));
+
+ /* Arbitrary user data */
+ eeprom_set_value(ftdi, USER_DATA_ADDR, cfg_getint(cfg, "user_data_addr"));
+ user_data_file = cfg_getstr(cfg, "user_data_file");
+ if (user_data_file && strlen(user_data_file) > 0)
+ {
+ int data_size;
+ struct stat st;
+
+ printf("User data file: %s\n", user_data_file);
+ /* Allocate a buffer for the user data */
+ user_data_buffer = (char *)malloc(max_eeprom_size);
+ if (user_data_buffer == NULL)
+ {
+ fprintf(stderr, "Malloc failed, aborting\n");
+ goto cleanup;
+ }
+
+ if (stat(user_data_file, &st))
+ {
+ printf ("Can't stat user data file %s.\n", user_data_file);
+ exit (-1);
+ }
+ if (st.st_size > max_eeprom_size)
+ printf("Warning: %s is too big, only reading %d bytes\n",
+ user_data_file, max_eeprom_size);
+ /* Read the user data file, no more than max_eeprom_size bytes */
+ FILE *fp = fopen(user_data_file, "rb");
+ if (fp == NULL)
+ {
+ printf ("Can't open user data file %s.\n", user_data_file);
+ exit (-1);
+ }
+ data_size = fread(user_data_buffer, 1, max_eeprom_size, fp);
+ fclose(fp);
+ if (data_size < 1)
+ {
+ printf ("Can't read user data file %s.\n", user_data_file);
+ exit (-1);
+ }
+ printf("User data size: %d\n", data_size);
+
+ ftdi_set_eeprom_user_data(ftdi, user_data_buffer, data_size);
+ }
+
if (command == COMMAND_ERASE)
{
if (size_check == -1)
{
- printf ("Sorry, the eeprom can only contain 128 bytes.\n");
+ printf ("Sorry, the eeprom can only contain %d bytes.\n", my_eeprom_size);
goto cleanup;
}
else if (size_check < 0)
cleanup:
if (eeprom_buf)
free(eeprom_buf);
+ if (user_data_buffer)
+ free(user_data_buffer);
if (command > 0)
{
printf("FTDI close: %d\n", ftdi_usb_close(ftdi));