On Mon, 2009-04-20 at 15:01 +0100, Ben Dooks wrote:
> On Mon, Apr 20, 2009 at 08:00:19AM +0200, Joern Kaipf wrote:
> > Hi Ben,
> > 
> > Ben Dooks write:
> > >I looked at src/jtag/ft2232.c and didn't notice anything there
> > >specific to the extra features in the H parts, such as the new
> > >speed selections. 
> > >
> > > Are there any patches / branches for supporting these devices,
> > > and if so when can any merge be expected?
> > 
> > I posted a patch same time ago (25.03.09), but I did't track if it was 
> > moved into the trunk.
> 
> I don't think it made trunk, url:
> 
> https://lists.berlios.de/pipermail/openocd-development/2009-March/005123.html

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.

For those who have the required library and want to test the patch, I
have attached my edited version.  It will apply against r1478, but it
may be a little fuzzy if applied on top of the series of patches that I
posted earlier today.

Cheers,

Zach

Index: src/jtag/ft2232.c
===================================================================
--- src/jtag/ft2232.c	(revision 1478)
+++ src/jtag/ft2232.c	(working copy)
@@ -70,11 +70,15 @@
 #define _DEBUG_USB_COMMS_
 #endif
 
+/* max TCK for the high speed devices 30000 kHz */
+#define	FTDI_2232H_4232H_MAX_TCK	30000
+
 int ft2232_execute_queue(void);
 
 int ft2232_speed(int speed);
 int ft2232_speed_div(int speed, int* khz);
 int ft2232_khz(int khz, int* jtag_speed);
+int ft2232_adaptive_clocking(int state);
 int ft2232_register_commands(struct command_context_s* cmd_ctx);
 int ft2232_init(void);
 int ft2232_quit(void);
@@ -101,7 +105,9 @@
 char*         ft2232_device_desc = NULL;
 char*         ft2232_serial  = NULL;
 char*         ft2232_layout  = NULL;
+unsigned char ft2232_rtck    = 0;
 unsigned char ft2232_latency = 2;
+unsigned int  ft2232_max_tck = 6000;
 
 #define MAX_USB_IDS 8
 /* vid = pid = 0 marks the end of the list */
@@ -125,7 +131,7 @@
 int  comstick_init(void);
 int  stm32stick_init(void);
 int  axm0432_jtag_init(void);
-int sheevaplug_init(void);
+int  sheevaplug_init(void);
 
 /* reset procedures for supported layouts */
 void usbjtag_reset(int trst, int srst);
@@ -171,6 +177,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
@@ -287,6 +294,23 @@
 	int retval;
 	u32 bytes_written;
 
+#if BUILD_FT2232_FTD2XX == 1
+	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 +332,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 +342,14 @@
 {
 	if (khz==0)
 	{
-		LOG_ERROR("RCLK not supported");
-		return ERROR_FAIL;
+#if BUILD_FT2232_LIBFTDI == 1
+                LOG_ERROR("RCLK not supported");
+                return ERROR_FAIL;
+#endif
+#if BUILD_FT2232_FTD2XX == 1
+		*jtag_speed = 0;
+		return ERROR_OK;
+#endif
 	}
 
 	/* Take a look in the FT2232 manual,
@@ -329,9 +359,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;
@@ -354,7 +384,38 @@
 	return ERROR_OK;
 }
 
+/* Commands only for FT2232H / FT4232H */
+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;
+}
+
+
 int ft2232_register_commands(struct command_context_s* cmd_ctx)
 {
 	register_command(cmd_ctx, NULL, "ft2232_device_desc", ft2232_handle_device_desc_command,
@@ -1533,6 +1594,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 +1727,25 @@
 		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);
+
+		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);
+		}
+	}
+
 	return ERROR_OK;
 }
 
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to