* autodetection if FS or HS device attachted -> adapt tck max
* enable adaptive clocking if HS device attached and jtag_khz = 0 in cfg (not 
tested yet)

Note:
The HS devices are currently only support by the drivers from FTDI and not 
from the libftdi. So using libftdi and RTCK support will cause a error 
message.
Index: jtag/ft2232.c
===================================================================
--- jtag/ft2232.c	(Revision 1433)
+++ jtag/ft2232.c	(Arbeitskopie)
@@ -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);
@@ -85,7 +89,6 @@
 int ft2232_handle_vid_pid_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
 int ft2232_handle_latency_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
 
-
 /**
  * Function ft2232_stableclocks
  * will send out \a num_cycles on the TCK line while the TAP(s)
@@ -101,7 +104,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 +130,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);
@@ -157,7 +162,7 @@
 	{ "comstick",             comstick_init,             comstick_reset,     NULL                    },
 	{ "stm32stick",           stm32stick_init,           stm32stick_reset,   NULL                    },
 	{ "axm0432_jtag",         axm0432_jtag_init,         axm0432_jtag_reset, NULL                    },
-	{"sheevaplug",            sheevaplug_init,           sheevaplug_reset,   NULL                    },
+	{ "sheevaplug",           sheevaplug_init,           sheevaplug_reset,   NULL                    },
 	{ NULL,                   NULL,                      NULL },
 };
 
@@ -171,6 +176,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
@@ -286,7 +292,23 @@
 	u8  buf[3];
 	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 +330,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 +340,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 +357,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 +382,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,
@@ -1257,8 +1316,6 @@
 			high_direction);
 }
 
-
-
 void sheevaplug_reset(int trst, int srst)
 {
 	if (trst == 1)
@@ -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,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;
 }
 
@@ -2306,7 +2385,6 @@
 	return ERROR_OK;
 }
 
-
 int sheevaplug_init(void)
 {
 	u8 buf[3];
@@ -2543,7 +2621,6 @@
 	return ERROR_OK;
 }
 
-
 static int ft2232_stableclocks(int num_cycles, jtag_command_t* cmd)
 {
 	int retval = 0;
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to