From 263d3ba0f28fa9e78e752e65537d98377eb29119 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 17 Jun 2011 21:06:22 +0200 Subject: [PATCH] Handle the FT232H CBUS Bits, Keep Values list numbered --- src/ftdi.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ftdi.h | 58 ++++++++++++++++++++++++++------------------ 2 files changed, 111 insertions(+), 24 deletions(-) diff --git a/src/ftdi.c b/src/ftdi.c index b6dba79..7aa0417 100644 --- a/src/ftdi.c +++ b/src/ftdi.c @@ -2261,10 +2261,36 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, char * manufacturer, eeprom->cbus_function[4] = CBUS_SLEEP; } else + { + if(ftdi->type == TYPE_232H) + { + int i; + for (i=0; i<10; i++) + eeprom->cbus_function[i] = CBUSH_TRISTATE; + } eeprom->size = -1; + } return 0; } +/*FTD2XX doesn't check for values not fitting in the ACBUS Signal oprtions*/ +void set_ft232h_cbus(struct ftdi_eeprom *eeprom, unsigned char * output) +{ + int i; + for(i=0; i<5;i++) + { + int mode_low, mode_high; + if (eeprom->cbus_function[2*i]> CBUSH_CLK7_5) + mode_low = CBUSH_TRISTATE; + else + mode_low = eeprom->cbus_function[2*i]; + if (eeprom->cbus_function[2*i+1]> CBUSH_CLK7_5) + mode_high = CBUSH_TRISTATE; + else + mode_high = eeprom->cbus_function[2*i]; + output[0x18+i] = mode_high <<4 | mode_low; + } +} /** Build binary buffer from ftdi_eeprom structure. Output is suitable for ftdi_write_eeprom(). @@ -2697,6 +2723,8 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi) if (eeprom->group1_slew == SLOW_SLEW) output[0x0d] |= SLOW_SLEW; + set_ft232h_cbus(eeprom, output); + output[0x1e] = eeprom->chip; fprintf(stderr,"FIXME: Build FT232H specific EEPROM settings\n"); break; @@ -2938,6 +2966,8 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) } else if (ftdi->type == TYPE_232H) { + int i; + eeprom->channel_a_type = buf[0x00] & 0xf; eeprom->channel_a_driver = (buf[0x00] & DRIVER_VCPH)?DRIVER_VCP:0; eeprom->clock_polarity = buf[0x01] & FT1284_CLK_IDLE_STATE; @@ -2951,6 +2981,11 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) eeprom->group1_schmitt = buf[0x0d] & IS_SCHMITT; eeprom->group1_slew = buf[0x0d] & SLOW_SLEW; + for(i=0; i<5; i++) + { + eeprom->cbus_function[2*i ] = buf[0x18+i] & 0x0f; + eeprom->cbus_function[2*i+1] = (buf[0x18+i] >> 4) & 0x0f; + } eeprom->chip = buf[0x1e]; /*FIXME: Decipher more values*/ } @@ -3036,6 +3071,11 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) } else if (ftdi->type == TYPE_232H) { + int i; + char *cbush_mux[] = {"TRISTATE","RXLED","TXLED", "TXRXLED","PWREN", + "SLEEP","DRIVE_0","DRIVE_1","IOMODE","TXDEN", + "CLK30","CLK15","CLK7_5" + }; fprintf(stdout,"ACBUS has %d mA drive%s%s\n", (eeprom->group0_drive+1) *4, (eeprom->group0_schmitt)?" Schmitt Input":"", @@ -3044,6 +3084,13 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose) (eeprom->group1_drive+1) *4, (eeprom->group1_schmitt)?" Schmitt Input":"", (eeprom->group1_slew)?" Slow Slew":""); + for (i=0; i<10; i++) + { + if (eeprom->cbus_function[i]<= CBUSH_CLK7_5 ) + fprintf(stdout,"C%d Function: %s\n", i, + cbush_mux[eeprom->cbus_function[i]]); + } + } if (ftdi->type == TYPE_R) @@ -3158,6 +3205,21 @@ int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu case CBUS_FUNCTION_4: *value = ftdi->eeprom->cbus_function[4]; break; + case CBUS_FUNCTION_5: + *value = ftdi->eeprom->cbus_function[5]; + break; + case CBUS_FUNCTION_6: + *value = ftdi->eeprom->cbus_function[6]; + break; + case CBUS_FUNCTION_7: + *value = ftdi->eeprom->cbus_function[7]; + break; + case CBUS_FUNCTION_8: + *value = ftdi->eeprom->cbus_function[8]; + break; + case CBUS_FUNCTION_9: + *value = ftdi->eeprom->cbus_function[8]; + break; case HIGH_CURRENT: *value = ftdi->eeprom->high_current; break; @@ -3306,6 +3368,21 @@ int ftdi_set_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value valu case CBUS_FUNCTION_4: ftdi->eeprom->cbus_function[4] = value; break; + case CBUS_FUNCTION_5: + ftdi->eeprom->cbus_function[5] = value; + break; + case CBUS_FUNCTION_6: + ftdi->eeprom->cbus_function[6] = value; + break; + case CBUS_FUNCTION_7: + ftdi->eeprom->cbus_function[7] = value; + break; + case CBUS_FUNCTION_8: + ftdi->eeprom->cbus_function[8] = value; + break; + case CBUS_FUNCTION_9: + ftdi->eeprom->cbus_function[9] = value; + break; case HIGH_CURRENT: ftdi->eeprom->high_current = value; break; diff --git a/src/ftdi.h b/src/ftdi.h index 22e1197..15518b5 100644 --- a/src/ftdi.h +++ b/src/ftdi.h @@ -242,9 +242,9 @@ struct ftdi_eeprom int channel_a_driver; int channel_b_driver; - /* Special function of FT232R devices (and possibly others as well) */ + /* Special function of FT232R/FT232H devices (and possibly others as well) */ /** CBUS pin function. See CBUS_xxx defines. */ - int cbus_function[5]; + int cbus_function[9]; /** Select hight current drive on R devices. */ int high_current; /** Select hight current drive on A channel (2232C */ @@ -373,28 +373,33 @@ enum ftdi_eeprom_value CBUS_FUNCTION_2 = 19, CBUS_FUNCTION_3 = 20, CBUS_FUNCTION_4 = 21, - HIGH_CURRENT = 22, - HIGH_CURRENT_A = 23, - HIGH_CURRENT_B = 24, - INVERT = 25, - GROUP0_DRIVE = 26, - GROUP0_SCHMITT = 27, - GROUP0_SLEW = 28, - GROUP1_DRIVE = 29, - GROUP1_SCHMITT = 30, - GROUP1_SLEW = 31, - GROUP2_DRIVE = 32, - GROUP2_SCHMITT = 33, - GROUP2_SLEW = 34, - GROUP3_DRIVE = 35, - GROUP3_SCHMITT = 36, - GROUP3_SLEW = 37, - CHIP_SIZE = 38, - CHIP_TYPE = 39, - POWER_SAVE = 40, - CLOCK_POLARITY = 41, - DATA_ORDER = 42, - FLOW_CONTROL = 43 + CBUS_FUNCTION_5 = 22, + CBUS_FUNCTION_6 = 23, + CBUS_FUNCTION_7 = 24, + CBUS_FUNCTION_8 = 25, + CBUS_FUNCTION_9 = 26, + HIGH_CURRENT = 27, + HIGH_CURRENT_A = 28, + HIGH_CURRENT_B = 29, + INVERT = 30, + GROUP0_DRIVE = 31, + GROUP0_SCHMITT = 32, + GROUP0_SLEW = 33, + GROUP1_DRIVE = 34, + GROUP1_SCHMITT = 35, + GROUP1_SLEW = 36, + GROUP2_DRIVE = 37, + GROUP2_SCHMITT = 38, + GROUP2_SLEW = 39, + GROUP3_DRIVE = 40, + GROUP3_SCHMITT = 41, + GROUP3_SLEW = 42, + CHIP_SIZE = 43, + CHIP_TYPE = 44, + POWER_SAVE = 45, + CLOCK_POLARITY = 46, + DATA_ORDER = 47, + FLOW_CONTROL = 48 }; /** @@ -418,6 +423,11 @@ enum ftdi_cbus_func {/* FIXME: Recheck value, especially the last */ 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}; +enum ftdi_cbush_func {/* FIXME: Recheck value, especially the last */ + 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 = 0xa, CBUSH_CLK15 = 0xb, CBUSH_CLK7_5 = 0xc}; + /** Invert TXD# */ #define INVERT_TXD 0x01 /** Invert RXD# */ -- 1.7.1