The branch, master has been updated
via be4bae37b3f851d7e06610fe474d84a3b2371efb (commit)
from 243f5f66d2f3eca83c64211263da97237dc96795 (commit)
- Log -----------------------------------------------------------------
commit be4bae37b3f851d7e06610fe474d84a3b2371efb
Author: Anders Larsen <al@xxxxxxxxxxx>
Date: Mon Apr 9 17:29:22 2012 +0200
Completed the support for the FT4232H chip
Added missing fields to the ftdi_eeprom structure and the encoding and
decoding functions.
The ftdi_eeprom utility forces DRIVER_VCP on and RS485 off for all channels,
but this could easily be made configurable, should the need arise.
Signed-off-by: Anders Larsen <al@xxxxxxxxxxx>
-----------------------------------------------------------------------
Summary of changes:
doc/EEPROM-structure | 40 ++++++++-------
ftdi_eeprom/main.c | 9 +++
src/ftdi.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++---
src/ftdi.h | 10 +++-
src/ftdi_i.h | 9 +++-
5 files changed, 175 insertions(+), 27 deletions(-)
diff --git a/doc/EEPROM-structure b/doc/EEPROM-structure
index c83337e..a1e9b02 100644
--- a/doc/EEPROM-structure
+++ b/doc/EEPROM-structure
@@ -9,27 +9,27 @@ Type | Use extra EEPROM space
FT2XXB | No
Byte.BIT| TYPE_AM TYPE_BM TYPE_2232C TYPE_R TYPE_2232H
TYPE_4232H
-00.0 | 0 0 channel_a_type channel_a_type
channel_a_type
-00.1 | 0 0 channel_a_type channel_a_type
channel_a_type
-00.2 | 0 0 channel_a_type high_current channel_a_type
channel_a_type
+00.0 | 0 0 channel_a_type channel_a_type 0
+00.1 | 0 0 channel_a_type channel_a_type 0
+00.2 | 0 0 channel_a_type high_current channel_a_type 0
00.3 | 0 0 channel_a_driver channel_a_driver channel_a_driver
channel_a_driver
00.4 | 0 0 high_current_a 0 0 0
00.5 | 0 0 0 0 0 0
00.6 | 0 0 0 0 0 0
-00.7 | 0 0 0 0 SUSPEND_DBUS7 0
+00.7 | 0 0 0 0 SUSPEND_DBUS7
channel_c_driver
On TYPE_R 00.3 set mean D2XX, on other devices VCP
-01.0 | 0 0 channel_b_type channel_b_type
channel_b_type
-01.1 | 0 0 channel_b_type channel_b_type
channel_b_type
-01.2 | 0 0 channel_b_type 0 channel_b_type
channel_b_type
+01.0 | 0 0 channel_b_type channel_b_type 0
+01.1 | 0 0 channel_b_type channel_b_type 0
+01.2 | 0 0 channel_b_type 0 channel_b_type 0
01.3 | 0 0 channel_b_driver 0 channel_b_driver
channel_b_driver
01.4 | 0 0 high_current_b 0 0 0
01.5 | 0 0 0 0 0 0
01.6 | 0 0 0 0 0
-01.7 | 0 0 0 0 0 0
+01.7 | 0 0 0 0 0
channel_d_driver
-Fixme: Missing 4232H validation and channel_c_driver, channel_d_driver,
channel_a|b|c|d_rs484enable
+Fixme: Missing 4232H validation
02 | Vendor ID (VID) LSB (all)
03 | Vendor ID (VID) MSB (all)
@@ -45,18 +45,22 @@ Fixme: Missing 4232H validation and channel_c_driver,
channel_d_driver, channel_
|
09 | Max power (mA/2)
|
-Byte.BIT| TYPE_AM TYPE_BM TYPE_2232C TYPE_R TYPE_2232H
TYPE_4232H
-0a.0 | 0 IsoIn IsoIn part A 0 0
0
-0a.1 | 0 IsoOut IsoOut part A 0 0
0
-0a.2 | 0 suspend_pull_down suspend_pull_down
suspend_pull_down
-0a.3 | 0 use_serial use_serial
+Byte.BIT| TYPE_AM TYPE_BM TYPE_2232C TYPE_R
TYPE_2232H TYPE_4232H
+0a.0 | 0 IsoIn IsoIn part A 0 0
0
+0a.1 | 0 IsoOut IsoOut part A 0 0
0
+0a.2 | 0 suspend_pull_down suspend_pull_down
suspend_pull_down suspend_pull_down
+0a.3 | 0 use_serial
use_serial use_serial
0a.4 | 0 change_usb_version change_usb_version
-0a.5 | 0 0 IsoIn part B 0 0
0
-0a.6 | 0 0 IsoOut part B 0 0
0
+0a.5 | 0 0 IsoIn part B 0 0
0
+0a.6 | 0 0 IsoOut part B 0 0
0
0a.7 | 0 - reserved
- |
-0b | TYPE_R Bitmask Invert, 0 else
+0b | TYPE_R Bitmask Invert, 0 else
+Byte.BIT| TYPE_4232H
+0b.4 | channel_a_rs485enable
+0b.5 | channel_b_rs485enable
+0b.6 | channel_c_rs485enable
+0b.7 | channel_d_rs485enable
Byte | TYPE_AM TYPE_BM TYPE_2232C TYPE_R TYPE_2232H
TYPE_4232H
0c | 0 USB-VER-LSB USB-VER-LSB 0 ? ?
diff --git a/ftdi_eeprom/main.c b/ftdi_eeprom/main.c
index 94cd7ec..ad7de93 100644
--- a/ftdi_eeprom/main.c
+++ b/ftdi_eeprom/main.c
@@ -297,6 +297,15 @@ int main(int argc, char *argv[])
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 (_erase > 0)
{
printf("FTDI erase eeprom: %d\n", ftdi_erase_eeprom(ftdi));
diff --git a/src/ftdi.c b/src/ftdi.c
index 59a9eea..8650be2 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -2369,7 +2369,6 @@ int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi,
char * manufacturer,
strcpy(eeprom->serial, serial);
}
-
if (ftdi->type == TYPE_R)
{
eeprom->max_power = 90;
@@ -2840,8 +2839,83 @@ int ftdi_eeprom_build(struct ftdi_context *ftdi)
break;
case TYPE_4232H:
+ if (eeprom->channel_a_driver == DRIVER_VCP)
+ output[0x00] |= DRIVER_VCP;
+ else
+ output[0x00] &= ~DRIVER_VCP;
+ if (eeprom->channel_b_driver == DRIVER_VCP)
+ output[0x01] |= DRIVER_VCP;
+ else
+ output[0x01] &= ~DRIVER_VCP;
+ if (eeprom->channel_c_driver == DRIVER_VCP)
+ output[0x00] |= (DRIVER_VCP << 4);
+ else
+ output[0x00] &= ~(DRIVER_VCP << 4);
+ if (eeprom->channel_d_driver == DRIVER_VCP)
+ output[0x01] |= (DRIVER_VCP << 4);
+ else
+ output[0x01] &= ~(DRIVER_VCP << 4);
+
+ if (eeprom->suspend_pull_downs == 1)
+ output[0x0a] |= 0x4;
+ else
+ output[0x0a] &= ~0x4;
+
+ if (eeprom->channel_a_rs485enable)
+ output[0x0b] |= CHANNEL_IS_RS485 << 0;
+ else
+ output[0x0b] &= ~(CHANNEL_IS_RS485 << 0);
+ if (eeprom->channel_b_rs485enable)
+ output[0x0b] |= CHANNEL_IS_RS485 << 1;
+ else
+ output[0x0b] &= ~(CHANNEL_IS_RS485 << 1);
+ if (eeprom->channel_c_rs485enable)
+ output[0x0b] |= CHANNEL_IS_RS485 << 2;
+ else
+ output[0x0b] &= ~(CHANNEL_IS_RS485 << 2);
+ if (eeprom->channel_d_rs485enable)
+ output[0x0b] |= CHANNEL_IS_RS485 << 3;
+ else
+ output[0x0b] &= ~(CHANNEL_IS_RS485 << 3);
+
+ if (eeprom->group0_drive > DRIVE_16MA)
+ output[0x0c] |= DRIVE_16MA;
+ else
+ output[0x0c] |= eeprom->group0_drive;
+ if (eeprom->group0_schmitt == IS_SCHMITT)
+ output[0x0c] |= IS_SCHMITT;
+ if (eeprom->group0_slew == SLOW_SLEW)
+ output[0x0c] |= SLOW_SLEW;
+
+ if (eeprom->group1_drive > DRIVE_16MA)
+ output[0x0c] |= DRIVE_16MA<<4;
+ else
+ output[0x0c] |= eeprom->group1_drive<<4;
+ if (eeprom->group1_schmitt == IS_SCHMITT)
+ output[0x0c] |= IS_SCHMITT<<4;
+ if (eeprom->group1_slew == SLOW_SLEW)
+ output[0x0c] |= SLOW_SLEW<<4;
+
+ if (eeprom->group2_drive > DRIVE_16MA)
+ output[0x0d] |= DRIVE_16MA;
+ else
+ output[0x0d] |= eeprom->group2_drive;
+ if (eeprom->group2_schmitt == IS_SCHMITT)
+ output[0x0d] |= IS_SCHMITT;
+ if (eeprom->group2_slew == SLOW_SLEW)
+ output[0x0d] |= SLOW_SLEW;
+
+ if (eeprom->group3_drive > DRIVE_16MA)
+ output[0x0d] |= DRIVE_16MA<<4;
+ else
+ output[0x0d] |= eeprom->group3_drive<<4;
+ if (eeprom->group3_schmitt == IS_SCHMITT)
+ output[0x0d] |= IS_SCHMITT<<4;
+ if (eeprom->group3_slew == SLOW_SLEW)
+ output[0x0d] |= SLOW_SLEW<<4;
+
output[0x18] = eeprom->chip;
- fprintf(stderr,"FIXME: Build FT4232H specific EEPROM settings\n");
+
break;
case TYPE_232H:
output[0x00] = type2bit(eeprom->channel_a_type, TYPE_232H);
@@ -3097,7 +3171,7 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int
verbose)
else if (ftdi->type == TYPE_R)
{
/* TYPE_R flags D2XX, not VCP as all others*/
- eeprom->channel_a_driver = (~buf[0x00]) & DRIVER_VCP;
+ eeprom->channel_a_driver = ~buf[0x00] & DRIVER_VCP;
eeprom->high_current = buf[0x00] & HIGH_CURRENT_DRIVE_R;
if ( (buf[0x01]&0x40) != 0x40)
fprintf(stderr,
@@ -3119,15 +3193,26 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int
verbose)
eeprom->cbus_function[3] = (buf[0x15] >> 4) & 0x0f;
eeprom->cbus_function[4] = buf[0x16] & 0x0f;
}
- else if ((ftdi->type == TYPE_2232H) ||(ftdi->type == TYPE_4232H))
+ else if ((ftdi->type == TYPE_2232H) || (ftdi->type == TYPE_4232H))
{
- eeprom->channel_a_type = bit2type(buf[0x00] & 0x7);
eeprom->channel_a_driver = buf[0x00] & DRIVER_VCP;
- eeprom->channel_b_type = bit2type(buf[0x01] & 0x7);
eeprom->channel_b_driver = buf[0x01] & DRIVER_VCP;
if (ftdi->type == TYPE_2232H)
+ {
+ eeprom->channel_a_type = bit2type(buf[0x00] & 0x7);
+ eeprom->channel_b_type = bit2type(buf[0x01] & 0x7);
eeprom->suspend_dbus7 = buf[0x01] & SUSPEND_DBUS7_BIT;
+ }
+ else
+ {
+ eeprom->channel_c_driver = (buf[0x00] >> 4) & DRIVER_VCP;
+ eeprom->channel_d_driver = (buf[0x01] >> 4) & DRIVER_VCP;
+ eeprom->channel_a_rs485enable = buf[0x0b] & (CHANNEL_IS_RS485 <<
0);
+ eeprom->channel_b_rs485enable = buf[0x0b] & (CHANNEL_IS_RS485 <<
1);
+ eeprom->channel_c_rs485enable = buf[0x0b] & (CHANNEL_IS_RS485 <<
2);
+ eeprom->channel_d_rs485enable = buf[0x0b] & (CHANNEL_IS_RS485 <<
3);
+ }
eeprom->chip = buf[0x18];
eeprom->group0_drive = buf[0x0c] & DRIVE_16MA;
@@ -3269,7 +3354,6 @@ int ftdi_eeprom_decode(struct ftdi_context *ftdi, int
verbose)
fprintf(stdout,"C%d Function: %s\n", i,
cbush_mux[eeprom->cbus_function[i]]);
}
-
}
if (ftdi->type == TYPE_R)
@@ -3375,6 +3459,24 @@ int ftdi_get_eeprom_value(struct ftdi_context *ftdi,
enum ftdi_eeprom_value valu
case CHANNEL_B_DRIVER:
*value = ftdi->eeprom->channel_b_driver;
break;
+ case CHANNEL_C_DRIVER:
+ *value = ftdi->eeprom->channel_c_driver;
+ break;
+ case CHANNEL_D_DRIVER:
+ *value = ftdi->eeprom->channel_d_driver;
+ break;
+ case CHANNEL_A_RS485:
+ *value = ftdi->eeprom->channel_a_rs485enable;
+ break;
+ case CHANNEL_B_RS485:
+ *value = ftdi->eeprom->channel_b_rs485enable;
+ break;
+ case CHANNEL_C_RS485:
+ *value = ftdi->eeprom->channel_c_rs485enable;
+ break;
+ case CHANNEL_D_RS485:
+ *value = ftdi->eeprom->channel_d_rs485enable;
+ break;
case CBUS_FUNCTION_0:
*value = ftdi->eeprom->cbus_function[0];
break;
@@ -3544,6 +3646,24 @@ int ftdi_set_eeprom_value(struct ftdi_context *ftdi,
enum ftdi_eeprom_value valu
case CHANNEL_B_DRIVER:
ftdi->eeprom->channel_b_driver = value;
break;
+ case CHANNEL_C_DRIVER:
+ ftdi->eeprom->channel_c_driver = value;
+ break;
+ case CHANNEL_D_DRIVER:
+ ftdi->eeprom->channel_d_driver = value;
+ break;
+ case CHANNEL_A_RS485:
+ ftdi->eeprom->channel_a_rs485enable = value;
+ break;
+ case CHANNEL_B_RS485:
+ ftdi->eeprom->channel_b_rs485enable = value;
+ break;
+ case CHANNEL_C_RS485:
+ ftdi->eeprom->channel_c_rs485enable = value;
+ break;
+ case CHANNEL_D_RS485:
+ ftdi->eeprom->channel_d_rs485enable = value;
+ break;
case CBUS_FUNCTION_0:
ftdi->eeprom->cbus_function[0] = value;
break;
diff --git a/src/ftdi.h b/src/ftdi.h
index 7bf5b6e..38b0668 100644
--- a/src/ftdi.h
+++ b/src/ftdi.h
@@ -301,7 +301,13 @@ enum ftdi_eeprom_value
POWER_SAVE = 45,
CLOCK_POLARITY = 46,
DATA_ORDER = 47,
- FLOW_CONTROL = 48
+ FLOW_CONTROL = 48,
+ CHANNEL_C_DRIVER = 49,
+ CHANNEL_D_DRIVER = 50,
+ CHANNEL_A_RS485 = 51,
+ CHANNEL_B_RS485 = 52,
+ CHANNEL_C_RS485 = 53,
+ CHANNEL_D_RS485 = 54,
};
/**
@@ -354,6 +360,8 @@ enum ftdi_cbush_func {/* FIXME: Recheck value, especially
the last */
#define CHANNEL_IS_CPU 0x4
#define CHANNEL_IS_FT1284 0x8
+#define CHANNEL_IS_RS485 0x10
+
#define DRIVE_4MA 0
#define DRIVE_8MA 1
#define DRIVE_12MA 2
diff --git a/src/ftdi_i.h b/src/ftdi_i.h
index dd2d29b..8d8c77e 100644
--- a/src/ftdi_i.h
+++ b/src/ftdi_i.h
@@ -68,7 +68,7 @@ struct ftdi_eeprom
/** serial number */
char *serial;
- /* 2232D/H(/FT4432H?) specific */
+ /* 2232D/H specific */
/* Hardware type, 0 = RS232 Uart, 1 = 245 FIFO, 2 = CPU FIFO,
4 = OPTO Isolate */
int channel_a_type;
@@ -76,6 +76,13 @@ struct ftdi_eeprom
/* Driver Type, 1 = VCP */
int channel_a_driver;
int channel_b_driver;
+ int channel_c_driver;
+ int channel_d_driver;
+ /* 4232H specific */
+ int channel_a_rs485enable;
+ int channel_b_rs485enable;
+ int channel_c_rs485enable;
+ int channel_d_rs485enable;
/* Special function of FT232R/FT232H devices (and possibly others as well)
*/
/** CBUS pin function. See CBUS_xxx defines. */
hooks/post-receive
--
A library to talk to FTDI chips
--
libftdi-git - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi-git+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
|