On Mon, 2009-04-20 at 20:51 -0700, Zach Welch wrote:
[snip] 
> That patch no longer applies cleanly.  I went ahead and cleaned it up
> (adding/removing whitespace), but it does not compile for me:
> 
> ft2232.c:300: error: 'FT_DEVICE_2232H' undeclared [...]
> ft2232.c:300: error: 'FT_DEVICE_4232H' undeclared [...]
> 
> This is a matter of requiring a newer version of the FTD2XX library; I
> started with 0.4.13 (too old) and had to upgrade to 0.4.16.  After the
> upgrade, everything compiles fine; however, I think we could allow
> continued use of older versions if this feature is not needed.
> 
> We can augment the configure script to check that the required support
> exists and conditionally compile it (or fail gracefully, if explicitly
> requested and not present).  That configure test should go in along with
> this new feature, as some distributions do not have the latest version
> packaged and ready for easy installation.

I have added the required autoconf support and tested it with both
versions of the FTD2XX library to ensure it works properly.  It even
allows explicit configuration (e.g. --enable-ftd2xx-highspeed), so it
can automatically detect whether the required symbols are present and
fail gracefully if they were explicitly requested.  It will also apply
cleanly to the new head.

I make few claims about its correctness, but its effects will be removed
with the configure option.  I think it's safe to apply this patch now.

Cheers,

Zach

Index: configure.in
===================================================================
--- configure.in	(revision 1486)
+++ configure.in	(working copy)
@@ -216,6 +216,10 @@
 AC_ARG_ENABLE(ft2232_ftd2xx,
   AS_HELP_STRING([--enable-ft2232_ftd2xx], [Enable building support for FT2232 based devices using the FTD2XX driver from ftdichip.com]), 
   [build_ft2232_ftd2xx=$enableval], [build_ft2232_ftd2xx=no])
+
+AC_ARG_ENABLE(ftd2xx_highspeed,
+  AS_HELP_STRING([--enable-ftd2xx-highspeed], [Enable building support for FT2232H and FT4232H-based devices (requires >=libftd2xx-0.4.16)]), 
+  [want_ftd2xx_highspeed=$enableval], [want_ftd2xx_highspeed=maybe])
  
 AC_ARG_ENABLE(amtjtagaccel,
   AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]), 
@@ -610,6 +614,32 @@
 	return 0;
 }
 ], [ AC_MSG_RESULT([Success!])] , [ AC_MSG_ERROR([Cannot build & run test program using ftd2xx.lib]) ] )
+
+AC_MSG_CHECKING([whether to build ftd2xx device support])
+AC_MSG_RESULT([$want_ftd2xx_highspeed])
+if test $want_ftd2xx_highspeed != no; then
+AC_MSG_CHECKING([for ftd2xx highspeed device support])
+AC_COMPILE_IFELSE([
+#include "confdefs.h"
+#if IS_WIN32
+#include "windows.h"
+#endif
+#include <stdio.h>
+#include <ftd2xx.h>
+DWORD x = FT_DEVICE_4232H;
+], [
+ AC_DEFINE(BUILD_FTD2XX_HIGHSPEED, [1], [Support FT2232H/FT4232HS with FTD2XX.])
+ build_ftd2xx_highspeed=yes
+], [
+ build_ftd2xx_highspeed=no
+] )
+AC_MSG_RESULT([$build_ftd2xx_highspeed])
+
+if test $want_ftd2xx_highspeed = yes -a $build_ftd2xx_highspeed = no; then
+   AC_MSG_ERROR([You need a newer FTD2XX driver (version 0.4.16 or later).])
+ fi
+fi
+
 LDFLAGS=$LDFLAGS_SAVE
 CFLAGS=$CFLAGS_SAVE
 fi
Index: src/jtag/ft2232.c
===================================================================
--- src/jtag/ft2232.c	(revision 1486)
+++ src/jtag/ft2232.c	(working copy)
@@ -96,12 +96,15 @@
  */
 static int ft2232_stableclocks(int num_cycles, jtag_command_t* cmd);
 
+/* max TCK for the high speed devices 30000 kHz */
+#define	FTDI_2232H_4232H_MAX_TCK	30000
 
 static char *        ft2232_device_desc_A = NULL;
 static char*         ft2232_device_desc = NULL;
 static char*         ft2232_serial  = NULL;
 static char*         ft2232_layout  = NULL;
 static unsigned char ft2232_latency = 2;
+static unsigned int  ft2232_max_tck = 6000;
 
 #define MAX_USB_IDS 8
 /* vid = pid = 0 marks the end of the list */
@@ -171,6 +174,7 @@
 
 #if BUILD_FT2232_FTD2XX == 1
 static FT_HANDLE           ftdih = NULL;
+static FT_DEVICE 	   device = 0;
 #elif BUILD_FT2232_LIBFTDI == 1
 static struct ftdi_context ftdic;
 #endif
@@ -280,13 +284,61 @@
 	return ERROR_OK;
 }
 
+#ifdef BUILD_FTD2XX_HIGHSPEED
+static int ft2232_adaptive_clocking(int state)
+{
+	u8  buf;
+	int retval;
+	u32 bytes_written;
 
+	if (state != 0)
+	{
+		state = 1;
+	}
+
+	if (state)
+	{
+		buf = 0x96;                  /* enable adaptive clocking */
+	}
+	else
+	{
+		buf = 0x97;                  /* disable adaptive clocking */
+	}
+
+	LOG_DEBUG("%2.2x ", buf);
+	if ( ( ( retval = ft2232_write(&buf, 1, &bytes_written) ) != ERROR_OK ) || (bytes_written != 1) )
+	{
+		LOG_ERROR("couldn't set adative clocking: %d", retval);
+		return retval;
+	}
+
+	return ERROR_OK;
+}
+#endif
+
 static int ft2232_speed(int speed)
 {
 	u8  buf[3];
 	int retval;
 	u32 bytes_written;
 
+#ifdef BUILD_FTD2XX_HIGHSPEED
+	if (speed == 0)
+	{
+		if ((device == FT_DEVICE_2232H) || (device == FT_DEVICE_4232H))
+		{
+			ft2232_adaptive_clocking(TRUE);
+		}
+		else
+		{
+			LOG_ERROR("device: %lu, doesn't support RTCK", device);
+		}	
+	}
+	else
+	{
+		ft2232_adaptive_clocking(FALSE);
+	}
+#endif
 	buf[0] = 0x86;                  /* command "set divisor" */
 	buf[1] = speed & 0xff;          /* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/
 	buf[2] = (speed >> 8) & 0xff;   /* valueH */
@@ -308,7 +360,7 @@
 	 * AN2232C-01 Command Processor for
 	 * MPSSE and MCU Host Bus. Chapter 3.8 */
 
-	*khz = 6000 / (1 + speed);
+	*khz = ft2232_max_tck / (1 + speed);
 
 	return ERROR_OK;
 }
@@ -318,8 +370,13 @@
 {
 	if (khz==0)
 	{
-		LOG_ERROR("RCLK not supported");
-		return ERROR_FAIL;
+#ifdef BUILD_FTD2XX_HIGHSPEED
+		*jtag_speed = 0;
+		return ERROR_OK;
+#else
+                LOG_ERROR("RCLK not supported");
+                return ERROR_FAIL;
+#endif
 	}
 
 	/* Take a look in the FT2232 manual,
@@ -329,9 +386,9 @@
 	 * We will calc here with a multiplier
 	 * of 10 for better rounding later. */
 
-	/* Calc speed, (6000 / khz) - 1 */
+	/* Calc speed, (ft2232_max_tck / khz) - 1 */
 	/* Use 65000 for better rounding */
-	*jtag_speed = (60000 / khz) - 10;
+	*jtag_speed = ((ft2232_max_tck*10) / khz) - 10;
 
 	/* Add 0.9 for rounding */
 	*jtag_speed += 9;
@@ -1533,6 +1590,9 @@
 static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int* try_more)
 {
 	FT_STATUS status;
+	DWORD deviceID;
+	char SerialNumber[16];
+	char Description[64]; 
 	DWORD     openex_flags  = 0;
 	char*     openex_string = NULL;
 	u8        latency_timer;
@@ -1663,6 +1723,27 @@
 		return ERROR_JTAG_INIT_FAILED;
 	}
 
+	if ( ( status = FT_GetDeviceInfo(ftdih, &device, &deviceID, SerialNumber, Description, NULL) ) != FT_OK )
+	{
+		LOG_ERROR("unable to get FT_GetDeviceInfo: %lu", status);
+		return ERROR_JTAG_INIT_FAILED;
+	}
+	else
+	{
+		LOG_INFO("device: %lu", device);
+		LOG_INFO("deviceID: %lu", deviceID);
+		LOG_INFO("SerialNumber: %s", SerialNumber);
+		LOG_INFO("Description: %s", Description);
+
+#ifdef BUILD_FTD2XX_HIGHSPEED
+		if ((device == FT_DEVICE_2232H) || (device == FT_DEVICE_4232H))
+		{
+			ft2232_max_tck = FTDI_2232H_4232H_MAX_TCK;
+			LOG_INFO("max TCK change to: %u kHz", ft2232_max_tck);
+		}
+#endif
+	}
+
 	return ERROR_OK;
 }
 
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to