Hi again,

you find attached a patch that applies to libftdi's master branch.
It fixes and cleans up the CBUS function constants and adds FT232H as well as FT230X CBUS function config support to the ftdi_eeprom tool.

This will actually allow you to program the CBUS functions on a FT230X in a way that matches what "FT Prog" does. The "eeprom.c" example will also now display the correct values on this chip.
See the patch file's comment for more details.

One thing I'm not sure about: I removed the CBUS_BB constant as FTDI's ftd2xx.h has nothing like it. But I haven't read the type R's data sheets. If there is indeed any use for this constant, just tell me and I will revise this patch.

Best regards,
Robin Haberkorn

btw.: Is this mailing list the preferred way of sending patches? Is there any official Github mirror I can send pull requests to?

--
Robin Haberkorn
Developer

metraTec GmbH
Werner-Heisenberg-Str. 1
39106 Magdeburg
Germany

haberk...@metratec.com
www.metratec.com


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscr...@developer.intra2net.com   
commit e904e9db37bebe98eb005d1f148fac0a63ee6e08
Author: Robin Haberkorn <haberk...@metratec.com>
Date:   Wed Jan 14 00:03:38 2015 +0100

    fixed ftdi_cbus_func and ftdi_cbush_func enumerations and introduced ftdi_cbusx_func
    
     * 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().

diff --git a/ftdi_eeprom/example.conf b/ftdi_eeprom/example.conf
index 2c50fda..28d1702 100644
--- a/ftdi_eeprom/example.conf
+++ b/ftdi_eeprom/example.conf
@@ -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 #
 ########
diff --git a/ftdi_eeprom/main.c b/ftdi_eeprom/main.c
index 2592796..c19d111 100644
--- a/ftdi_eeprom/main.c
+++ b/ftdi_eeprom/main.c
@@ -41,27 +41,72 @@
 #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;
diff --git a/src/ftdi.c b/src/ftdi.c
index ea487d0..1e3b445 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -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
diff --git a/src/ftdi.h b/src/ftdi.h
index 07fcd71..debf053 100644
--- a/src/ftdi.h
+++ b/src/ftdi.h
@@ -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_SLEEP = 5, CBUSH_DRIVE_0 = 6, CBUSG_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_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
+};
+
+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# */

Reply via email to