fixed ftdi_cbus_func and ftdi_cbush_func enumerations and introduced ftdi_cbusx_func
authorRobin Haberkorn <haberkorn@metratec.com>
Tue, 13 Jan 2015 23:03:38 +0000 (00:03 +0100)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Thu, 12 Feb 2015 21:28:48 +0000 (22:28 +0100)
* removed CBUS_BB. D2XX doesn't have it, so I don't think it's actually valid.

* CBUSH_TXLED/CBUSH_RXLED had the wrong values probably because the author
  looked at an outdated D2XX ftdi.h
  These values were also wrong in various mux tables of ftdi.c resulting
  e.g. in confusing outputs of the eeprom.c example.

* ftdi_cbush_func was extended to contain FT230X CBUS functions.
  However, the clock functions are different on FT-X and it is also
  confusing to use CBUSH constants on FT-X chips, so I introduced another
  enum ftdi_cbusx_func with CBUSX constants.

* Added support for setting CBUS functions on FT232H and FT230X in ftdi_eeprom.
  To support these chips, special cbushN and cbusxN options have been
  introduced.
  Possible values of the "cbus" options now match the ftdi.h constant names.
  Libconfuse string lists are no longer used as option types since they do not
  represent enumerations but lists.

* When "cbus" options are missing in ftdi_eeprom config files, keep the
  chip defaults as set by ftdi_eeprom_initdefaults().

ftdi_eeprom/example.conf
ftdi_eeprom/main.c
src/ftdi.c
src/ftdi.h

index 2c50fda..28d1702 100644 (file)
@@ -24,6 +24,34 @@ suspend_pull_downs=false     # Enable suspend pull downs for lower power
 change_usb_version=false       # Change USB Version
 usb_version=0x0200             # Only used when change_usb_version is enabled
 
+# Only used on FT-R chips (when omitted, use chip defaults)
+# Possible values correspond to enum ftdi_cbus_func.
+cbus0=TXLED
+cbus1=RXLED
+cbus2=TXDEN
+cbus3=PWREN
+cbus4=SLEEP
+
+# Only used on FT232H chips (when omitted, use chip defaults)
+# Possible values correspond to enum ftdi_cbush_func.
+cbush0=TRISTATE
+cbush1=TRISTATE
+cbush2=TRISTATE
+cbush3=TRISTATE
+cbush4=TRISTATE
+cbush5=TRISTATE
+cbush6=TRISTATE
+cbush7=TRISTATE
+cbush8=TRISTATE
+cbush9=TRISTATE
+
+# Only used on FT230X chips (when omitted, use chip defaults)
+# Possible values correspond to enum ftdi_cbusx_func.
+cbusx0=TXDEN
+cbusx1=RXLED
+cbusx2=TXLED
+cbusx3=SLEEP
+
 ########
 # Misc #
 ########
index 2592796..c19d111 100644 (file)
 #include <ftdi.h>
 #include <ftdi_eeprom_version.h>
 
-static int str_to_cbus(char *str, int max_allowed)
+static int parse_cbus(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result)
 {
-#define MAX_OPTION 14
-    const char* options[MAX_OPTION] =
+    static const char* options[] =
     {
-        "TXDEN", "PWREN", "RXLED", "TXLED", "TXRXLED", "SLEEP",
-        "CLK48", "CLK24", "CLK12", "CLK6",
-        "IO_MODE", "BITBANG_WR", "BITBANG_RD", "SPECIAL"
+        "TXDEN", "PWREN", "RXLED", "TXLED", "TXRXLED", "SLEEP", "CLK48",
+        "CLK24", "CLK12", "CLK6", "IOMODE", "BB_WR", "BB_RD"
     };
+
     int i;
-    max_allowed += 1;
-    if (max_allowed > MAX_OPTION) max_allowed = MAX_OPTION;
-    for (i=0; i<max_allowed; i++)
+    for (i=0; i<sizeof(options)/sizeof(*options); i++)
     {
-        if (!(strcmp(options[i], str)))
+        if (!(strcmp(options[i], value)))
         {
-            return i;
+            *(int *)result = i;
+            return 0;
         }
     }
-    printf("WARNING: Invalid cbus option '%s'\n", str);
-    return 0;
+
+    cfg_error(cfg, "Invalid %s option '%s'", cfg_opt_name(opt), value);
+    return -1;
+}
+
+static int parse_cbush(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result)
+{
+    static const char* options[] =
+    {
+        "TRISTATE", "TXLED", "RXLED", "TXRXLED", "PWREN", "SLEEP",
+        "DRIVE_0", "DRIVE1", "IOMODE", "TXDEN", "CLK30", "CLK15", "CLK7_5"
+    };
+
+    int i;
+    for (i=0; i<sizeof(options)/sizeof(*options); i++)
+    {
+        if (!(strcmp(options[i], value)))
+        {
+            *(int *)result = i;
+            return 0;
+        }
+    }
+
+    cfg_error(cfg, "Invalid %s option '%s'", cfg_opt_name(opt), value);
+    return -1;
+}
+
+static int parse_cbusx(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result)
+{
+    static const char* options[] =
+    {
+        "TRISTATE", "TXLED", "RXLED", "TXRXLED", "PWREN", "SLEEP",
+        "DRIVE_0", "DRIVE1", "IOMODE", "TXDEN", "CLK24", "CLK12",
+        "CLK6", "BAT_DETECT", "BAT_DETECT_NEG", "I2C_TXE", "I2C_RXF", "VBUS_SENSE",
+        "BB_WR", "BB_RD", "TIME_STAMP", "AWAKE"
+    };
+
+    int i;
+    for (i=0; i<sizeof(options)/sizeof(*options); i++)
+    {
+        if (!(strcmp(options[i], value)))
+        {
+            *(int *)result = i;
+            return 0;
+        }
+    }
+
+    cfg_error(cfg, "Invalid %s option '%s'", cfg_opt_name(opt), value);
+    return -1;
 }
 
 /**
@@ -126,11 +171,25 @@ int main(int argc, char *argv[])
         CFG_STR("filename", "", 0),
         CFG_BOOL("flash_raw", cfg_false, 0),
         CFG_BOOL("high_current", cfg_false, 0),
-        CFG_STR_LIST("cbus0", "{TXDEN,PWREN,RXLED,TXLED,TXRXLED,SLEEP,CLK48,CLK24,CLK12,CLK6,IO_MODE,BITBANG_WR,BITBANG_RD,SPECIAL}", 0),
-        CFG_STR_LIST("cbus1", "{TXDEN,PWREN,RXLED,TXLED,TXRXLED,SLEEP,CLK48,CLK24,CLK12,CLK6,IO_MODE,BITBANG_WR,BITBANG_RD,SPECIAL}", 0),
-        CFG_STR_LIST("cbus2", "{TXDEN,PWREN,RXLED,TXLED,TXRXLED,SLEEP,CLK48,CLK24,CLK12,CLK6,IO_MODE,BITBANG_WR,BITBANG_RD,SPECIAL}", 0),
-        CFG_STR_LIST("cbus3", "{TXDEN,PWREN,RXLED,TXLED,TXRXLED,SLEEP,CLK48,CLK24,CLK12,CLK6,IO_MODE,BITBANG_WR,BITBANG_RD,SPECIAL}", 0),
-        CFG_STR_LIST("cbus4", "{TXDEN,PWRON,RXLED,TXLED,TX_RX_LED,SLEEP,CLK48,CLK24,CLK12,CLK6}", 0),
+        CFG_INT_CB("cbus0", -1, 0, parse_cbus),
+        CFG_INT_CB("cbus1", -1, 0, parse_cbus),
+        CFG_INT_CB("cbus2", -1, 0, parse_cbus),
+        CFG_INT_CB("cbus3", -1, 0, parse_cbus),
+        CFG_INT_CB("cbus4", -1, 0, parse_cbus),
+        CFG_INT_CB("cbush0", -1, 0, parse_cbush),
+        CFG_INT_CB("cbush1", -1, 0, parse_cbush),
+        CFG_INT_CB("cbush2", -1, 0, parse_cbush),
+        CFG_INT_CB("cbush3", -1, 0, parse_cbush),
+        CFG_INT_CB("cbush4", -1, 0, parse_cbush),
+        CFG_INT_CB("cbush5", -1, 0, parse_cbush),
+        CFG_INT_CB("cbush6", -1, 0, parse_cbush),
+        CFG_INT_CB("cbush7", -1, 0, parse_cbush),
+        CFG_INT_CB("cbush8", -1, 0, parse_cbush),
+        CFG_INT_CB("cbush9", -1, 0, parse_cbush),
+        CFG_INT_CB("cbusx0", -1, 0, parse_cbusx),
+        CFG_INT_CB("cbusx1", -1, 0, parse_cbusx),
+        CFG_INT_CB("cbusx2", -1, 0, parse_cbusx),
+        CFG_INT_CB("cbusx3", -1, 0, parse_cbusx),
         CFG_BOOL("invert_txd", cfg_false, 0),
         CFG_BOOL("invert_rxd", cfg_false, 0),
         CFG_BOOL("invert_rts", cfg_false, 0),
@@ -286,11 +345,55 @@ int main(int argc, char *argv[])
     eeprom_set_value(ftdi, CHIP_TYPE, cfg_getint(cfg, "eeprom_type"));
 
     eeprom_set_value(ftdi, HIGH_CURRENT, cfg_getbool(cfg, "high_current"));
-    eeprom_set_value(ftdi, CBUS_FUNCTION_0, str_to_cbus(cfg_getstr(cfg, "cbus0"), 13));
-    eeprom_set_value(ftdi, CBUS_FUNCTION_1, str_to_cbus(cfg_getstr(cfg, "cbus1"), 13));
-    eeprom_set_value(ftdi, CBUS_FUNCTION_2, str_to_cbus(cfg_getstr(cfg, "cbus2"), 13));
-    eeprom_set_value(ftdi, CBUS_FUNCTION_3, str_to_cbus(cfg_getstr(cfg, "cbus3"), 13));
-    eeprom_set_value(ftdi, CBUS_FUNCTION_4, str_to_cbus(cfg_getstr(cfg, "cbus4"), 9));
+
+    if (ftdi->type == TYPE_R)
+    {
+        if (cfg_getint(cfg, "cbus0") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_0, cfg_getint(cfg, "cbus0"));
+        if (cfg_getint(cfg, "cbus1") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_1, cfg_getint(cfg, "cbus1"));
+        if (cfg_getint(cfg, "cbus2") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_2, cfg_getint(cfg, "cbus2"));
+        if (cfg_getint(cfg, "cbus3") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_3, cfg_getint(cfg, "cbus3"));
+        if (cfg_getint(cfg, "cbus4") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_4, cfg_getint(cfg, "cbus4"));
+    }
+    else if (ftdi->type == TYPE_232H)
+    {
+        if (cfg_getint(cfg, "cbush0") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_0, cfg_getint(cfg, "cbush0"));
+        if (cfg_getint(cfg, "cbush1") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_1, cfg_getint(cfg, "cbush1"));
+        if (cfg_getint(cfg, "cbush2") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_2, cfg_getint(cfg, "cbush2"));
+        if (cfg_getint(cfg, "cbush3") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_3, cfg_getint(cfg, "cbush3"));
+        if (cfg_getint(cfg, "cbush4") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_4, cfg_getint(cfg, "cbush4"));
+        if (cfg_getint(cfg, "cbush5") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_5, cfg_getint(cfg, "cbush5"));
+        if (cfg_getint(cfg, "cbush6") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_6, cfg_getint(cfg, "cbush6"));
+        if (cfg_getint(cfg, "cbush7") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_7, cfg_getint(cfg, "cbush7"));
+        if (cfg_getint(cfg, "cbush8") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_8, cfg_getint(cfg, "cbush8"));
+        if (cfg_getint(cfg, "cbush9") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_9, cfg_getint(cfg, "cbush9"));
+    }
+    else if (ftdi->type == TYPE_230X)
+    {
+        if (cfg_getint(cfg, "cbusx0") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_0, cfg_getint(cfg, "cbusx0"));
+        if (cfg_getint(cfg, "cbusx1") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_1, cfg_getint(cfg, "cbusx1"));
+        if (cfg_getint(cfg, "cbusx2") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_2, cfg_getint(cfg, "cbusx2"));
+        if (cfg_getint(cfg, "cbusx3") != -1)
+            eeprom_set_value(ftdi, CBUS_FUNCTION_3, cfg_getint(cfg, "cbusx3"));
+    }
+
     int invert = 0;
     if (cfg_getbool(cfg, "invert_rxd")) invert |= INVERT_RXD;
     if (cfg_getbool(cfg, "invert_txd")) invert |= INVERT_TXD;
index ea487d0..1e3b445 100644 (file)
@@ -2392,10 +2392,10 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer,
     {
         eeprom->max_power = 90;
         eeprom->size = 0x100;
-        eeprom->cbus_function[0] = CBUSH_TXDEN;
-        eeprom->cbus_function[1] = CBUSH_RXLED;
-        eeprom->cbus_function[2] = CBUSH_TXLED;
-        eeprom->cbus_function[3] = CBUSH_SLEEP;
+        eeprom->cbus_function[0] = CBUSX_TXDEN;
+        eeprom->cbus_function[1] = CBUSX_RXLED;
+        eeprom->cbus_function[2] = CBUSX_TXLED;
+        eeprom->cbus_function[3] = CBUSX_SLEEP;
     }
     else
     {
@@ -2488,7 +2488,7 @@ int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, char * manufacturer,
 }
 
 
-/*FTD2XX doesn't check for values not fitting in the ACBUS Signal oprtions*/
+/*FTD2XX doesn't check for values not fitting in the ACBUS Signal options*/
 void set_ft232h_cbus(struct ftdi_eeprom *eeprom, unsigned char * output)
 {
     int i;
@@ -2843,22 +2843,22 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
             output[0x0C] = eeprom->usb_version & 0xff;
             output[0x0D] = (eeprom->usb_version>>8) & 0xff;
 
-            if (eeprom->cbus_function[0] > CBUS_BB)
+            if (eeprom->cbus_function[0] > CBUS_BB_RD)
                 output[0x14] = CBUS_TXLED;
             else
                 output[0x14] = eeprom->cbus_function[0];
 
-            if (eeprom->cbus_function[1] > CBUS_BB)
+            if (eeprom->cbus_function[1] > CBUS_BB_RD)
                 output[0x14] |= CBUS_RXLED<<4;
             else
                 output[0x14] |= eeprom->cbus_function[1]<<4;
 
-            if (eeprom->cbus_function[2] > CBUS_BB)
+            if (eeprom->cbus_function[2] > CBUS_BB_RD)
                 output[0x15] = CBUS_TXDEN;
             else
                 output[0x15] = eeprom->cbus_function[2];
 
-            if (eeprom->cbus_function[3] > CBUS_BB)
+            if (eeprom->cbus_function[3] > CBUS_BB_RD)
                 output[0x15] |= CBUS_PWREN<<4;
             else
                 output[0x15] |= eeprom->cbus_function[3]<<4;
@@ -3493,7 +3493,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
         }
         else if (ftdi->type == TYPE_232H)
         {
-            char *cbush_mux[] = {"TRISTATE","RXLED","TXLED", "TXRXLED","PWREN",
+            char *cbush_mux[] = {"TRISTATE","TXLED","RXLED", "TXRXLED","PWREN",
                                  "SLEEP","DRIVE_0","DRIVE_1","IOMODE","TXDEN",
                                  "CLK30","CLK15","CLK7_5"
                                 };
@@ -3514,7 +3514,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
         }
         else if (ftdi->type == TYPE_230X)
         {
-            char *cbush_mux[] = {"TRISTATE","RXLED","TXLED", "TXRXLED","PWREN",
+            char *cbusx_mux[] = {"TRISTATE","TXLED","RXLED", "TXRXLED","PWREN",
                                  "SLEEP","DRIVE_0","DRIVE_1","IOMODE","TXDEN",
                                  "CLK24","CLK12","CLK6","BAT_DETECT","BAT_DETECT#",
                                  "I2C_TXE#", "I2C_RXF#", "VBUS_SENSE", "BB_WR#",
@@ -3530,8 +3530,8 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
                     (eeprom->group1_slew)?" Slow Slew":"");
             for (i=0; i<4; i++)
             {
-                if (eeprom->cbus_function[i]<= CBUSH_AWAKE)
-                    fprintf(stdout,"CBUS%d Function: %s\n", i, cbush_mux[eeprom->cbus_function[i]]);
+                if (eeprom->cbus_function[i]<= CBUSX_AWAKE)
+                    fprintf(stdout,"CBUS%d Function: %s\n", i, cbusx_mux[eeprom->cbus_function[i]]);
             }
 
             if (eeprom->invert)
@@ -3551,7 +3551,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose)
 
             for (i=0; i<5; i++)
             {
-                if (eeprom->cbus_function[i]<CBUS_BB)
+                if (eeprom->cbus_function[i]<=CBUS_BB_RD)
                     fprintf(stdout,"C%d Function: %s\n", i,
                             cbus_mux[eeprom->cbus_function[i]]);
                 else
index 42f4cc1..debf053 100644 (file)
@@ -350,20 +350,27 @@ struct ftdi_device_list
 #define POWER_SAVE_DISABLE_H 0x80
 
 #define USE_SERIAL_NUM 0x08
-enum ftdi_cbus_func  /* FIXME: Recheck value, especially the last */
+enum ftdi_cbus_func
 {
     CBUS_TXDEN = 0, CBUS_PWREN = 1, CBUS_RXLED = 2, CBUS_TXLED = 3, CBUS_TXRXLED = 4,
     CBUS_SLEEP = 5, CBUS_CLK48 = 6, CBUS_CLK24 = 7, CBUS_CLK12 = 8, CBUS_CLK6 =  9,
-    CBUS_IOMODE = 0xa, CBUS_BB_WR = 0xb, CBUS_BB_RD = 0xc, CBUS_BB   = 0xd
+    CBUS_IOMODE = 0xa, CBUS_BB_WR = 0xb, CBUS_BB_RD = 0xc
 };
 
-enum ftdi_cbush_func  /* FIXME: Recheck value, especially the last */
+enum ftdi_cbush_func
 {
-    CBUSH_TRISTATE = 0, CBUSH_RXLED = 1, CBUSH_TXLED = 2, CBUSH_TXRXLED = 3, CBUSH_PWREN = 4,
+    CBUSH_TRISTATE = 0, CBUSH_TXLED = 1, CBUSH_RXLED = 2, CBUSH_TXRXLED = 3, CBUSH_PWREN = 4,
     CBUSH_SLEEP = 5, CBUSH_DRIVE_0 = 6, CBUSH_DRIVE1 = 7, CBUSH_IOMODE = 8, CBUSH_TXDEN =  9,
-    CBUSH_CLK30 = 10, CBUSH_CLK15 = 11, CBUSH_CLK7_5 = 12, CBUSH_BAT_DETECT = 13,
-    CBUSH_BAT_DETECT_NEG = 14, CBUSH_I2C_TXE = 15, CBUSH_I2C_RXF = 16, CBUSH_VBUS_SENSE = 17,
-    CBUSH_BB_WR = 18, CBUSH_BB_RD = 19, CBUSH_TIME_STAMP = 20, CBUSH_AWAKE = 21,
+    CBUSH_CLK30 = 10, CBUSH_CLK15 = 11, CBUSH_CLK7_5 = 12
+};
+
+enum ftdi_cbusx_func
+{
+    CBUSX_TRISTATE = 0, CBUSX_TXLED = 1, CBUSX_RXLED = 2, CBUSX_TXRXLED = 3, CBUSX_PWREN = 4,
+    CBUSX_SLEEP = 5, CBUSX_DRIVE_0 = 6, CBUSX_DRIVE1 = 7, CBUSX_IOMODE = 8, CBUSX_TXDEN =  9,
+    CBUSX_CLK24 = 10, CBUSX_CLK12 = 11, CBUSX_CLK6 = 12, CBUSX_BAT_DETECT = 13,
+    CBUSX_BAT_DETECT_NEG = 14, CBUSX_I2C_TXE = 15, CBUSX_I2C_RXF = 16, CBUSX_VBUS_SENSE = 17,
+    CBUSX_BB_WR = 18, CBUSX_BB_RD = 19, CBUSX_TIME_STAMP = 20, CBUSX_AWAKE = 21
 };
 
 /** Invert TXD# */