This adds:

* calls to tap_get_tms_path_len(start, end);

* adds buffer overflow protection in the form of a few well placed asserts().

* numerous comments and documentation references.

* attempts to do diligent state transition logging, making it easier to track moves to ANY tap state at any time. To enable this, compile with _DEBUG_JTAG_IO_ enabled and then up your debug logging level to DEBUG level.


It is likely that more changes will be needed, but before the patch got too big, I'm offering smaller portions so they can be swallowed more easily. I did not solve the seg fault problem, but the asserts will likely trap them when I get back to the XSVF support.
The state transition logging is really nice.


Dick

Index: src/jtag/ft2232.c
===================================================================
--- src/jtag/ft2232.c	(revision 1548)
+++ src/jtag/ft2232.c	(working copy)
@@ -26,6 +26,9 @@
  * found here:
  * http://www.ftdichip.com/Documents/AppNotes/AN2232C-01_MPSSE_Cmnd.pdf
  * Hereafter this is called the "MPSSE Spec".
+ *
+ * The datasheet for the ftdichip.com's FT2232D part is here:
+ * http://www.ftdichip.com/Documents/DataSheets/DS_FT2232D.pdf
  */
 
 
@@ -50,7 +53,9 @@
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <assert.h>
 
+
 /* FT2232 access library includes */
 #if BUILD_FT2232_FTD2XX == 1
 #include <ftd2xx.h>
@@ -66,7 +71,9 @@
 static int ft2232_register_commands(struct command_context_s* cmd_ctx);
 static int ft2232_init(void);
 static int ft2232_quit(void);
+static void ft2232_add_pathmove( tap_state_t* path, int num_states );
 
+
 static int ft2232_handle_device_desc_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
 static int ft2232_handle_serial_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
 static int ft2232_handle_layout_command(struct command_context_s* cmd_ctx, char* cmd, char** args, int argc);
@@ -92,6 +99,7 @@
 static unsigned char ft2232_latency = 2;
 
 #define MAX_USB_IDS 8
+
 /* vid = pid = 0 marks the end of the list */
 static u16 ft2232_vid[MAX_USB_IDS + 1] = { 0x0403, 0 };
 static u16 ft2232_pid[MAX_USB_IDS + 1] = { 0x6010, 0 };
@@ -167,15 +175,108 @@
 static jtag_command_t* first_unsent;        /* next command that has to be sent */
 static int             require_send;
 
+
+/*	http://urjtag.wiki.sourceforge.net/Cable+FT2232 says:
+
+	"There is a significant difference between libftdi and libftd2xx. The latter
+	one allows to schedule up to 64*64 bytes of result data while libftdi fails
+	with more than 4*64. As a consequence, the FT2232 driver is forced to
+	perform around 16x more USB transactions for long command streams with TDO
+	capture when running with libftdi."
+
+	No idea how we get
+	#define FT2232_BUFFER_SIZE 131072
+	a comment would have been nice.
+*/
+
+#define FT2232_BUFFER_SIZE 131072
+
 static u8*             ft2232_buffer = NULL;
 static int             ft2232_buffer_size  = 0;
 static int             ft2232_read_pointer = 0;
 static int             ft2232_expect_read  = 0;
 
-#define FT2232_BUFFER_SIZE 131072
-#define BUFFER_ADD         ft2232_buffer[ft2232_buffer_size++]
-#define BUFFER_READ        ft2232_buffer[ft2232_read_pointer++]
+/**
+ * Function buffer_write
+ * writes a byte into the byte buffer, "ft2232_buffer", which must be sent later.
+ * @param val is the byte to send.
+ */
+static inline void buffer_write( u8 val )
+{
+	assert( (unsigned) ft2232_buffer_size < (unsigned) FT2232_BUFFER_SIZE );
+	ft2232_buffer[ft2232_buffer_size++] = val;
+}
 
+/**
+ * Function buffer_read
+ * returns a byte from the byte buffer.
+ */
+static inline u8 buffer_read(void)
+{
+	assert( ft2232_read_pointer < ft2232_buffer_size );
+	return ft2232_buffer[ft2232_read_pointer++];
+}
+
+
+/**
+ * Function buffer_send_tms_sequence_no_read
+ * clocks out \a bit_count bits on the TMS line, starting with the least
+ * significant bit of tms_bits and progressing to more significant bits.
+ * The MPSSE command "Clock Data to TMS/CS Pin (no Read)" is used for this.
+ */
+static void buffer_send_tms_sequence_no_read( int tms_bits, int bit_count )
+{
+	u8	tms_byte;
+	int	i;
+	int	tms_ndx;				/* bit index into tms_byte */
+
+	assert( bit_count > 0 );
+
+	//LOG_DEBUG("tms_bits=0x%08x, bit_count=%d", tms_bits, bit_count );
+
+	for (tms_byte = tms_ndx = i = 0;   i < bit_count;   ++i, tms_bits>>=1)
+	{
+		if (tms_bits & 1)
+			tms_byte |= (1<<tms_ndx);
+
+		/* 	we wrote a bit to tms_byte just above, increment bit index.  if bit was zero
+			also increment.
+		*/
+		++tms_ndx;
+
+		if( tms_ndx == 7 )
+		{
+			/* MPSSE command "Clock Data to TMS/CS Pin (no Read)" */
+			buffer_write( 0x4b );
+			buffer_write( tms_ndx - 1 );
+			buffer_write( tms_byte );
+
+			tms_ndx = 0;
+			tms_byte = 0;
+		}
+	}
+
+	if (tms_ndx)
+	{
+		/* MPSSE command "Clock Data to TMS/CS Pin (no Read)" */
+		buffer_write( 0x4b );
+		buffer_write( tms_ndx - 1 );
+		buffer_write( tms_byte );
+	}
+}
+
+
+/**
+ * Function get_tms_buffer_requirements
+ * returns what buffer_send_tms_sequence_*() will consume if called with
+ * same \a bit_count.
+ */
+static inline int get_tms_buffer_requirements( int bit_count )
+{
+	return ((bit_count + 6) * 3)/7;
+}
+
+
 jtag_interface_t ft2232_interface =
 {
 	.name               = "ft2232",
@@ -275,9 +376,9 @@
 	int retval;
 	u32 bytes_written;
 
-	buf[0] = 0x86;                  /* command "set divisor" */
-	buf[1] = speed & 0xff;          /* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/
-	buf[2] = (speed >> 8) & 0xff;   /* valueH */
+	buf[0] = 0x86;                  	/* command "set divisor" */
+	buf[1] = (u8) speed;          	/* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/
+	buf[2] = (u8) (speed >> 8);   	/* valueH */
 
 	LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
 	if ( ( ( retval = ft2232_write(buf, 3, &bytes_written) ) != ERROR_OK ) || (bytes_written != 3) )
@@ -379,7 +480,7 @@
 
 	while (num_bytes-- > 1)
 	{
-		buffer[cur_byte] = BUFFER_READ;
+		buffer[cur_byte] = buffer_read();
 		cur_byte++;
 		bits_left -= 8;
 	}
@@ -388,10 +489,10 @@
 
 	if (bits_left > 1)
 	{
-		buffer[cur_byte] = BUFFER_READ >> 1;
+		buffer[cur_byte] = buffer_read() >> 1;
 	}
 
-	buffer[cur_byte] = ( buffer[cur_byte] | ( (BUFFER_READ & 0x02) << 6 ) ) >> (8 - bits_left);
+	buffer[cur_byte] = ( buffer[cur_byte] | ( (buffer_read() & 0x02) << 6 ) ) >> (8 - bits_left);
 }
 
 
@@ -535,77 +636,105 @@
 }
 
 
-static void ft2232_add_pathmove(pathmove_command_t* cmd)
+/**
+ * Function ft2232_add_pathmove
+ * moves the TAP controller from the current state to a new state through the
+ * given path, where path is an array of tap_state_t's.
+ *
+ * @param path is an array of tap_stat_t which gives the states to traverse through
+ *   ending with the last state at path[num_states-1]
+ * @param num_states is the count of state steps to move through
+ */
+static void ft2232_add_pathmove( tap_state_t* path, int num_states )
 {
-	int num_states = cmd->num_states;
-	int state_count = 0;
+	int	tms_bits = 0;
+	int	state_ndx;
 
-	while (num_states)
+	assert( (unsigned) num_states <= 32u );		/* tms_bits only holds 32 bits */
+
+	/* this loop verifies that the path is legal and logs each state in the path */
+	for( state_ndx = 0; state_ndx < num_states;  ++state_ndx )
 	{
-		u8  tms_byte = 0;       /* zero this on each MPSSE batch */
+		tap_state_t	desired_next_state = path[state_ndx];
 
-		int bit_count = 0;
+		if (tap_state_transition(tap_get_state(), false) == desired_next_state )
+			;	/* bit within tms_bits at index state_ndx is already zero */
+		else if (tap_state_transition(tap_get_state(), true) == desired_next_state )
+			tms_bits |= (1<<state_ndx);
+		else
+		{
+			LOG_ERROR( "BUG: %s -> %s isn't a valid TAP transition",
+					tap_state_name(tap_get_state()), tap_state_name(desired_next_state) );
+			exit(-1);
+		}
 
-		int num_states_batch = num_states > 7 ? 7 : num_states;
+		/* never change states except in public view */
+		tap_set_state(desired_next_state);
+	}
 
-		/* command "Clock Data to TMS/CS Pin (no Read)" */
-		BUFFER_ADD = 0x4b;
+	buffer_send_tms_sequence_no_read( tms_bits, num_states );
 
-		/* number of states remaining */
-		BUFFER_ADD = num_states_batch - 1;
+	tap_set_end_state(tap_get_state());
+}
 
-		while (num_states_batch--)
-		{
-			if (tap_state_transition(tap_get_state(), false) == cmd->path[state_count])
-				buf_set_u32(&tms_byte, bit_count++, 1, 0x0);
-			else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count])
-				buf_set_u32(&tms_byte, bit_count++, 1, 0x1);
-			else
-			{
-				LOG_ERROR( "BUG: %s -> %s isn't a valid TAP transition", tap_state_name(
-								 tap_get_state() ), tap_state_name(cmd->path[state_count]) );
-				exit(-1);
-			}
 
-			tap_set_state(cmd->path[state_count]);
-			state_count++;
-			num_states--;
-		}
+/**
+ * Function ft2232_add_pathmove_states
+ * moves the TAP controller from the current state to a new state through the
+ * given path, where path is an array of tms bits to clock out.  A major purpose
+ * of this function is to do diligent state transition logging via the
+ * tap_set_state() function.
+ *
+ * @param start is the initial state for the move, and is 1/2 of a pair
+ *   of states which allow convenient lookup of the required TMS pattern to
+ *   move from this state to another.
+ *
+ * @param end is the destination state for the move, and is 1/2 of a pair
+ *   of states which allow convenient lookup of the required TMS pattern to
+ *   move to this state from another.
+ */
+static void ft2232_add_pathmove_states( tap_state_t start, tap_state_t end )
+{
+	/* do the 2 lookups */
+	int tms_bits  = tap_get_tms_path(start, end);
+	int tms_count = tap_get_tms_path_len(start, end);
 
-		BUFFER_ADD = tms_byte;
+	int state_ndx;
+
+	LOG_DEBUG( "start=%s end=%s", tap_state_name(start), tap_state_name(end) );
+
+	for( state_ndx = 0; state_ndx < tms_count;  ++state_ndx )
+	{
+		bool		bit = (tms_bits & (1<<state_ndx));
+
+		/* do the state transitions in view of the public, always */
+		tap_set_state( tap_state_transition(tap_get_state(), bit) );
 	}
-	
-	tap_set_end_state(tap_get_state());
+
+	buffer_send_tms_sequence_no_read( tms_bits, tms_count );
 }
 
 
-void ft2232_add_scan(int ir_scan, enum scan_type type, u8* buffer, int scan_size)
+static void ft2232_add_scan(int ir_scan, enum scan_type type, u8* buffer, int scan_size)
 {
 	int num_bytes = (scan_size + 7) / 8;
 	int bits_left = scan_size;
 	int cur_byte  = 0;
 	int last_bit;
 
-	if ( !( ( !ir_scan && (tap_get_state() == TAP_DRSHIFT) )
-	   || (    ir_scan && (tap_get_state() == TAP_IRSHIFT) ) ) )
+	if ( !ir_scan )
 	{
-		/* command "Clock Data to TMS/CS Pin (no Read)" */
-		BUFFER_ADD = 0x4b;
-
-		BUFFER_ADD = 0x6;       /* scan 7 bits */
-
-		/* TMS data bits */
-		if (ir_scan)
+		if (tap_get_state() != TAP_DRSHIFT)
 		{
-			BUFFER_ADD = tap_get_tms_path(tap_get_state(), TAP_IRSHIFT);
-			tap_set_state(TAP_IRSHIFT);
+			ft2232_add_pathmove_states( tap_get_state(), TAP_DRSHIFT );
 		}
-		else
+	}
+	else
+	{
+		if (tap_get_state() != TAP_IRSHIFT)
 		{
-			BUFFER_ADD = tap_get_tms_path(tap_get_state(), TAP_DRSHIFT);
-			tap_set_state(TAP_DRSHIFT);
+			ft2232_add_pathmove_states( tap_get_state(), TAP_IRSHIFT );
 		}
-		/* LOG_DEBUG("added TMS scan (no read)"); */
 	}
 
 	/* add command for complete bytes */
@@ -615,33 +744,34 @@
 		if (type == SCAN_IO)
 		{
 			/* Clock Data Bytes In and Out LSB First */
-			BUFFER_ADD = 0x39;
+			buffer_write( 0x39 );
 			/* LOG_DEBUG("added TDI bytes (io %i)", num_bytes); */
 		}
 		else if (type == SCAN_OUT)
 		{
 			/* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */
-			BUFFER_ADD = 0x19;
+			buffer_write( 0x19 );
 			/* LOG_DEBUG("added TDI bytes (o)"); */
 		}
 		else if (type == SCAN_IN)
 		{
 			/* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */
-			BUFFER_ADD = 0x28;
+			buffer_write( 0x28 );
 			/* LOG_DEBUG("added TDI bytes (i %i)", num_bytes); */
 		}
 
 		thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1);
 		num_bytes    -= thisrun_bytes;
-		BUFFER_ADD    = (thisrun_bytes - 1) & 0xff;
-		BUFFER_ADD    = ( (thisrun_bytes - 1) >> 8 ) & 0xff;
 
+		buffer_write( (u8) (thisrun_bytes - 1) );
+		buffer_write( (u8) ((thisrun_bytes - 1) >> 8) );
+
 		if (type != SCAN_IN)
 		{
 			/* add complete bytes */
 			while (thisrun_bytes-- > 0)
 			{
-				BUFFER_ADD = buffer[cur_byte];
+				buffer_write( buffer[cur_byte] );
 				cur_byte++;
 				bits_left -= 8;
 			}
@@ -664,24 +794,24 @@
 		if (type == SCAN_IO)
 		{
 			/* Clock Data Bits In and Out LSB First */
-			BUFFER_ADD = 0x3b;
+			buffer_write( 0x3b );
 			/* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
 		}
 		else if (type == SCAN_OUT)
 		{
 			/* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
-			BUFFER_ADD = 0x1b;
+			buffer_write( 0x1b );
 			/* LOG_DEBUG("added TDI bits (o)"); */
 		}
 		else if (type == SCAN_IN)
 		{
 			/* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
-			BUFFER_ADD = 0x2a;
+			buffer_write( 0x2a );
 			/* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
 		}
-		BUFFER_ADD = bits_left - 2;
+		buffer_write( bits_left - 2 );
 		if (type != SCAN_IN)
-			BUFFER_ADD = buffer[cur_byte];
+			buffer_write( buffer[cur_byte] );
 	}
 
 	if ( (  ir_scan && (tap_get_end_state() == TAP_IRSHIFT) )
@@ -690,23 +820,23 @@
 		if (type == SCAN_IO)
 		{
 			/* Clock Data Bits In and Out LSB First */
-			BUFFER_ADD = 0x3b;
+			buffer_write( 0x3b );
 			/* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
 		}
 		else if (type == SCAN_OUT)
 		{
 			/* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
-			BUFFER_ADD = 0x1b;
+			buffer_write( 0x1b );
 			/* LOG_DEBUG("added TDI bits (o)"); */
 		}
 		else if (type == SCAN_IN)
 		{
 			/* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
-			BUFFER_ADD = 0x2a;
+			buffer_write( 0x2a );
 			/* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
 		}
-		BUFFER_ADD = 0x0;
-		BUFFER_ADD = last_bit;
+		buffer_write( 0x0 );
+		buffer_write( last_bit );
 	}
 	else
 	{
@@ -714,18 +844,18 @@
 		if (type != SCAN_OUT)
 		{
 			/* Clock Data to TMS/CS Pin with Read */
-			BUFFER_ADD = 0x6b;
+			buffer_write( 0x6b );
 			/* LOG_DEBUG("added TMS scan (read)"); */
 		}
 		else
 		{
 			/* Clock Data to TMS/CS Pin (no Read) */
-			BUFFER_ADD = 0x4b;
+			buffer_write( 0x4b );
 			/* LOG_DEBUG("added TMS scan (no read)"); */
 		}
-		BUFFER_ADD = 0x6;   /* scan 7 bits */
 
-		BUFFER_ADD = tap_get_tms_path( tap_get_state(), tap_get_end_state() ) | (last_bit << 7);
+		buffer_write( 0x6 );   /* scan 7 bits */
+		buffer_write( tap_get_tms_path( tap_get_state(), tap_get_end_state() ) | (last_bit << 7) );
 		tap_set_state( tap_get_end_state() );
 	}
 }
@@ -752,14 +882,7 @@
 
 	if (tap_get_state() != TAP_DRSHIFT)
 	{
-		/* command "Clock Data to TMS/CS Pin (no Read)" */
-		BUFFER_ADD = 0x4b;
-
-		BUFFER_ADD = 0x6;       /* scan 7 bits */
-
-		/* TMS data bits */
-		BUFFER_ADD = tap_get_tms_path(tap_get_state(), TAP_DRSHIFT);
-		tap_set_state(TAP_DRSHIFT);
+		ft2232_add_pathmove_states( tap_get_state(), TAP_DRSHIFT );
 	}
 
 	if ( ( retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written) ) != ERROR_OK )
@@ -778,34 +901,34 @@
 		if (type == SCAN_IO)
 		{
 			/* Clock Data Bytes In and Out LSB First */
-			BUFFER_ADD = 0x39;
+			buffer_write( 0x39 );
 			/* LOG_DEBUG("added TDI bytes (io %i)", num_bytes); */
 		}
 		else if (type == SCAN_OUT)
 		{
 			/* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */
-			BUFFER_ADD = 0x19;
+			buffer_write( 0x19 );
 			/* LOG_DEBUG("added TDI bytes (o)"); */
 		}
 		else if (type == SCAN_IN)
 		{
 			/* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */
-			BUFFER_ADD = 0x28;
+			buffer_write( 0x28 );
 			/* LOG_DEBUG("added TDI bytes (i %i)", num_bytes); */
 		}
 
 		thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1);
 		thisrun_read  = thisrun_bytes;
 		num_bytes    -= thisrun_bytes;
-		BUFFER_ADD    = (thisrun_bytes - 1) & 0xff;
-		BUFFER_ADD    = ( (thisrun_bytes - 1) >> 8 ) & 0xff;
+		buffer_write( (u8) (thisrun_bytes - 1) );
+		buffer_write( (u8) ( (thisrun_bytes - 1) >> 8 ));
 
 		if (type != SCAN_IN)
 		{
 			/* add complete bytes */
 			while (thisrun_bytes-- > 0)
 			{
-				BUFFER_ADD = buffer[cur_byte];
+				buffer_write( buffer[cur_byte] );
 				cur_byte++;
 				bits_left -= 8;
 			}
@@ -849,24 +972,24 @@
 		if (type == SCAN_IO)
 		{
 			/* Clock Data Bits In and Out LSB First */
-			BUFFER_ADD = 0x3b;
+			buffer_write( 0x3b );
 			/* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
 		}
 		else if (type == SCAN_OUT)
 		{
 			/* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
-			BUFFER_ADD = 0x1b;
+			buffer_write( 0x1b );
 			/* LOG_DEBUG("added TDI bits (o)"); */
 		}
 		else if (type == SCAN_IN)
 		{
 			/* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
-			BUFFER_ADD = 0x2a;
+			buffer_write( 0x2a );
 			/* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
 		}
-		BUFFER_ADD = bits_left - 2;
+		buffer_write( bits_left - 2 );
 		if (type != SCAN_IN)
-			BUFFER_ADD = buffer[cur_byte];
+			buffer_write( buffer[cur_byte] );
 
 		if (type != SCAN_OUT)
 			thisrun_read += 2;
@@ -877,23 +1000,23 @@
 		if (type == SCAN_IO)
 		{
 			/* Clock Data Bits In and Out LSB First */
-			BUFFER_ADD = 0x3b;
+			buffer_write( 0x3b );
 			/* LOG_DEBUG("added TDI bits (io) %i", bits_left - 1); */
 		}
 		else if (type == SCAN_OUT)
 		{
 			/* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
-			BUFFER_ADD = 0x1b;
+			buffer_write( 0x1b );
 			/* LOG_DEBUG("added TDI bits (o)"); */
 		}
 		else if (type == SCAN_IN)
 		{
 			/* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
-			BUFFER_ADD = 0x2a;
+			buffer_write( 0x2a );
 			/* LOG_DEBUG("added TDI bits (i %i)", bits_left - 1); */
 		}
-		BUFFER_ADD = 0x0;
-		BUFFER_ADD = last_bit;
+		buffer_write( 0x0 );
+		buffer_write( last_bit );
 	}
 	else
 	{
@@ -901,17 +1024,17 @@
 		if (type != SCAN_OUT)
 		{
 			/* Clock Data to TMS/CS Pin with Read */
-			BUFFER_ADD = 0x6b;
+			buffer_write( 0x6b );
 			/* LOG_DEBUG("added TMS scan (read)"); */
 		}
 		else
 		{
 			/* Clock Data to TMS/CS Pin (no Read) */
-			BUFFER_ADD = 0x4b;
+			buffer_write( 0x4b );
 			/* LOG_DEBUG("added TMS scan (no read)"); */
 		}
-		BUFFER_ADD = 0x6;
-		BUFFER_ADD = tap_get_tms_path( tap_get_state(), tap_get_end_state() ) | (last_bit << 7);
+		buffer_write( 0x6 );
+		buffer_write( tap_get_tms_path( tap_get_state(), tap_get_end_state() ) | (last_bit << 7) );
 		tap_set_state( tap_get_end_state() );
 	}
 
@@ -953,6 +1076,7 @@
 	{
 		/* complete bytes */
 		predicted_size += CEIL(num_bytes, 65536) * 3;
+
 		/* remaining bits - 1 (up to 7) */
 		predicted_size += ( (scan_size - 1) % 8 ) ? 2 : 0;
 	}
@@ -960,6 +1084,7 @@
 	{
 		/* complete bytes */
 		predicted_size += num_bytes + CEIL(num_bytes, 65536) * 3;
+
 		/* remaining bits -1 (up to 7) */
 		predicted_size += ( (scan_size - 1) % 8 ) ? 3 : 0;
 	}
@@ -1023,9 +1148,9 @@
 	}
 
 	/* command "set data bits low byte" */
-	BUFFER_ADD = 0x80;
-	BUFFER_ADD = low_output;
-	BUFFER_ADD = low_direction;
+	buffer_write( 0x80 );
+	buffer_write( low_output );
+	buffer_write( low_direction );
 }
 
 
@@ -1062,9 +1187,9 @@
 	}
 
 	/* command "set data bits high byte" */
-	BUFFER_ADD = 0x82;
-	BUFFER_ADD = high_output;
-	BUFFER_ADD = high_direction;
+	buffer_write( 0x82 );
+	buffer_write( high_output );
+	buffer_write( high_direction );
 	LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output,
 			high_direction);
 }
@@ -1097,9 +1222,9 @@
 	}
 
 	/* command "set data bits high byte" */
-	BUFFER_ADD = 0x82;
-	BUFFER_ADD = high_output;
-	BUFFER_ADD = high_direction;
+	buffer_write( 0x82 );
+	buffer_write( high_output );
+	buffer_write( high_direction );
 	LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output,
 			high_direction);
 }
@@ -1127,9 +1252,9 @@
 	}
 
 	/* command "set data bits low byte" */
-	BUFFER_ADD = 0x82;
-	BUFFER_ADD = high_output;
-	BUFFER_ADD = high_direction;
+	buffer_write( 0x82 );
+	buffer_write( high_output );
+	buffer_write( high_direction );
 	LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output,
 			high_direction);
 }
@@ -1156,9 +1281,9 @@
 	}
 
 	/* command "set data bits low byte" */
-	BUFFER_ADD = 0x80;
-	BUFFER_ADD = low_output;
-	BUFFER_ADD = low_direction;
+	buffer_write( 0x80 );
+	buffer_write( low_output );
+	buffer_write( low_direction );
 	LOG_DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst, srst, low_output, low_direction);
 }
 
@@ -1177,9 +1302,9 @@
 	}
 
 	/* command "set data bits low byte" */
-	BUFFER_ADD = 0x80;
-	BUFFER_ADD = low_output;
-	BUFFER_ADD = low_direction;
+	buffer_write( 0x80 );
+	buffer_write( low_output );
+	buffer_write( low_direction );
 	LOG_DEBUG("srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", srst, low_output, low_direction);
 }
 
@@ -1205,9 +1330,9 @@
 	}
 
 	/* command "set data bits high byte" */
-	BUFFER_ADD = 0x82;
-	BUFFER_ADD = high_output;
-	BUFFER_ADD = high_direction;
+	buffer_write( 0x82 );
+	buffer_write( high_output );
+	buffer_write( high_direction );
 	LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output,
 			high_direction);
 }
@@ -1234,14 +1359,14 @@
 	}
 
 	/* command "set data bits low byte" */
-	BUFFER_ADD = 0x80;
-	BUFFER_ADD = low_output;
-	BUFFER_ADD = low_direction;
+	buffer_write( 0x80 );
+	buffer_write( low_output );
+	buffer_write( low_direction );
 
 	/* command "set data bits high byte" */
-	BUFFER_ADD = 0x82;
-	BUFFER_ADD = high_output;
-	BUFFER_ADD = high_direction;
+	buffer_write( 0x82 );
+	buffer_write( high_output );
+	buffer_write( high_direction );
 	LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output,
 			high_direction);
 }
@@ -1261,9 +1386,9 @@
 		high_output |= nSRSTnOE;
 
 	/* command "set data bits high byte" */
-	BUFFER_ADD = 0x82;
-	BUFFER_ADD = high_output;
-	BUFFER_ADD = high_direction;
+	buffer_write( 0x82 );
+	buffer_write( high_output );
+	buffer_write( high_direction );
 	LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);
 }
 
@@ -1293,13 +1418,18 @@
 			cmd->cmd.runtest->end_state);
 	/* only send the maximum buffer size that FT2232C can handle */
 	predicted_size = 0;
+
 	if (tap_get_state() != TAP_IDLE)
 		predicted_size += 3;
+
 	predicted_size += 3 * CEIL(cmd->cmd.runtest->num_cycles, 7);
+
 	if ( (cmd->cmd.runtest->end_state != TAP_INVALID) && (cmd->cmd.runtest->end_state != TAP_IDLE) )
 		predicted_size += 3;
+
 	if ( (cmd->cmd.runtest->end_state == TAP_INVALID) && (tap_get_end_state() != TAP_IDLE) )
 		predicted_size += 3;
+
 	if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
 	{
 		if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
@@ -1307,29 +1437,28 @@
 		require_send = 0;
 		first_unsent = cmd;
 	}
+
 	if (tap_get_state() != TAP_IDLE)
 	{
-		/* command "Clock Data to TMS/CS Pin (no Read)" */
-		BUFFER_ADD = 0x4b;
-		BUFFER_ADD = 0x6;    /* scan 7 bits */
-
-		/* TMS data bits */
-		BUFFER_ADD = tap_get_tms_path(tap_get_state(), TAP_IDLE);
-		tap_set_state(TAP_IDLE);
+		ft2232_add_pathmove_states( tap_get_state(), TAP_IDLE );
 		require_send = 1;
 	}
+
 	i = cmd->cmd.runtest->num_cycles;
 	while (i > 0)
 	{
+		/* there are no state transitions in this loop */
+
 		/* command "Clock Data to TMS/CS Pin (no Read)" */
-		BUFFER_ADD = 0x4b;
+		buffer_write( 0x4b );
 
 		/* scan 7 bits */
-		BUFFER_ADD = (i > 7) ? 6 : (i - 1);
+		buffer_write( (i > 7) ? 6 : (i - 1) );
 
 		/* TMS data bits */
-		BUFFER_ADD = 0x0;
+		buffer_write( 0x0 );
 		tap_set_state(TAP_IDLE);
+
 		i -= (i > 7) ? 7 : i;
 		/* LOG_DEBUG("added TMS scan (no read)"); */
 	}
@@ -1339,15 +1468,9 @@
 
 	if ( tap_get_state() != tap_get_end_state() )
 	{
-		/* command "Clock Data to TMS/CS Pin (no Read)" */
-		BUFFER_ADD = 0x4b;
-		/* scan 7 bit */
-		BUFFER_ADD = 0x6;
-		/* TMS data bits */
-		BUFFER_ADD = tap_get_tms_path( tap_get_state(), tap_get_end_state() );
-		tap_set_state( tap_get_end_state() );
-		/* LOG_DEBUG("added TMS scan (no read)"); */
+		ft2232_add_pathmove_states( tap_get_state(), tap_get_end_state() );
 	}
+
 	require_send = 1;
 #ifdef _DEBUG_JTAG_IO_
 	LOG_DEBUG( "runtest: %i, end in %s", cmd->cmd.runtest->num_cycles, tap_state_name( tap_get_end_state() ) );
@@ -1373,23 +1496,14 @@
 		require_send = 0;
 		first_unsent = cmd;
 	}
+
 	if (cmd->cmd.statemove->end_state != TAP_INVALID)
 		ft2232_end_state(cmd->cmd.statemove->end_state);
 
-	/* command "Clock Data to TMS/CS Pin (no Read)" */
-	BUFFER_ADD = 0x4b;
+	/* move to end state */
+	ft2232_add_pathmove_states( tap_get_state(), tap_get_end_state() );
 
-	BUFFER_ADD = 0x6;       /* scan 7 bits */
-
-			/* TMS data bits */
-	BUFFER_ADD = tap_get_tms_path( tap_get_state(), tap_get_end_state() );
-	/* LOG_DEBUG("added TMS scan (no read)"); */
-	tap_set_state( tap_get_end_state() );
 	require_send = 1;
-#ifdef _DEBUG_JTAG_IO_
-	LOG_DEBUG( "statemove: %s", tap_state_name( tap_get_end_state() ) );
-#endif
-	
 	return retval;
 }
 
@@ -1411,7 +1525,8 @@
 		require_send = 0;
 		first_unsent = cmd;
 	}
-	ft2232_add_pathmove(cmd->cmd.pathmove);
+
+	ft2232_add_pathmove( cmd->cmd.pathmove->path, cmd->cmd.pathmove->num_states );
 	require_send = 1;
 #ifdef _DEBUG_JTAG_IO_
 	LOG_DEBUG( "pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states,
@@ -1443,6 +1558,7 @@
 		/* current command */
 		if (cmd->cmd.scan->end_state != TAP_INVALID)
 			ft2232_end_state(cmd->cmd.scan->end_state);
+
 		ft2232_large_scan(cmd->cmd.scan, type, buffer, scan_size);
 		require_send = 0;
 		first_unsent = cmd->next;
@@ -1455,8 +1571,10 @@
 		LOG_DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)",
 				first_unsent,
 				cmd);
+
 		if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
 			retval = ERROR_JTAG_QUEUE_FAILED;
+
 		require_send = 0;
 		first_unsent = cmd;
 	}
@@ -1466,8 +1584,10 @@
 		ft2232_end_state(cmd->cmd.scan->end_state);
 	ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
 	require_send = 1;
+
 	if (buffer)
 		free(buffer);
+
 #ifdef _DEBUG_JTAG_IO_
 	LOG_DEBUG( "%s scan, %i bits, end in %s", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
 			tap_state_name( tap_get_end_state() ) );
@@ -1550,17 +1670,17 @@
 
 	switch (cmd->type)
 	{
-		case JTAG_END_STATE: retval = ft2232_execute_end_state(cmd); break;
-		case JTAG_RESET:	 retval = ft2232_execute_reset(cmd); break;
-		case JTAG_RUNTEST:   retval = ft2232_execute_runtest(cmd); break;
-		case JTAG_STATEMOVE: retval = ft2232_execute_statemove(cmd); break;
-		case JTAG_PATHMOVE:  retval = ft2232_execute_pathmove(cmd); break;
-		case JTAG_SCAN: 	 retval = ft2232_execute_scan(cmd); break;
-		case JTAG_SLEEP:	 retval = ft2232_execute_sleep(cmd); break;
-		case JTAG_STABLECLOCKS: retval = ft2232_execute_stableclocks(cmd); break;
-		default:
-			LOG_ERROR("BUG: unknown JTAG command type encountered");
-			exit(-1);	
+	case JTAG_END_STATE: 	retval = ft2232_execute_end_state(cmd); break;
+	case JTAG_RESET:	 		retval = ft2232_execute_reset(cmd); break;
+	case JTAG_RUNTEST:   	retval = ft2232_execute_runtest(cmd); break;
+	case JTAG_STATEMOVE: 	retval = ft2232_execute_statemove(cmd); break;
+	case JTAG_PATHMOVE:  	retval = ft2232_execute_pathmove(cmd); break;
+	case JTAG_SCAN: 	 		retval = ft2232_execute_scan(cmd); break;
+	case JTAG_SLEEP:	 		retval = ft2232_execute_sleep(cmd); break;
+	case JTAG_STABLECLOCKS: 	retval = ft2232_execute_stableclocks(cmd); break;
+	default:
+		LOG_ERROR("BUG: unknown JTAG command type encountered");
+		exit(-1);
 	}
 	return retval;
 }
@@ -1589,6 +1709,7 @@
 	{
 		if (ft2232_execute_command(cmd) != ERROR_OK)
 			retval = ERROR_JTAG_QUEUE_FAILED;
+
 		/* Start reading input before FT2232 TX buffer fills up */
 		cmd = cmd->next;
 		if (ft2232_expect_read > 256)
@@ -1650,17 +1771,22 @@
 	}
 
 	status = FT_OpenEx(openex_string, openex_flags, &ftdih);
-	if( status != FT_OK ){
+	if( status != FT_OK )
+	{
 		// under Win32, the FTD2XX driver appends an "A" to the end
 		// of the description, if we tried by the desc, then
 		// try by the alternate "A" description.
-		if( openex_string == ft2232_device_desc ){
+		if( openex_string == ft2232_device_desc )
+		{
 			// Try the alternate method.
 			openex_string = ft2232_device_desc_A;
 			status = FT_OpenEx(openex_string, openex_flags, &ftdih);
-			if( status == FT_OK ){
+			if( status == FT_OK )
+			{
 				// yea, the "alternate" method worked!
-			} else {
+			}
+			else
+			{
 				// drat, give the user a meaningfull message.
 				// telling the use we tried *BOTH* methods.
 				LOG_WARNING("Unable to open FTDI Device tried: '%s' and '%s'\n",
@@ -1680,7 +1806,9 @@
 			*try_more = 1;
 			return ERROR_JTAG_INIT_FAILED;
 		}
+
 		LOG_ERROR("unable to open ftdi device: %lu", status);
+
 		status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY);
 		if (status == FT_OK)
 		{
@@ -2401,7 +2529,7 @@
 
 	if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
 	{
-		LOG_ERROR("couldn't initialize FT2232 with 'sheevaplug' layout"); 
+		LOG_ERROR("couldn't initialize FT2232 with 'sheevaplug' layout");
 		return ERROR_JTAG_INIT_FAILED;
 	}
 
@@ -2429,7 +2557,7 @@
 
 	if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
 	{
-		LOG_ERROR("couldn't initialize FT2232 with 'sheevaplug' layout"); 
+		LOG_ERROR("couldn't initialize FT2232 with 'sheevaplug' layout");
 		return ERROR_JTAG_INIT_FAILED;
 	}
 
@@ -2452,9 +2580,9 @@
 		high_output |= 0x08;
 	}
 
-	BUFFER_ADD = 0x82;
-	BUFFER_ADD = high_output;
-	BUFFER_ADD = high_direction;
+	buffer_write( 0x82 );
+	buffer_write( high_output );
+	buffer_write( high_direction );
 }
 
 
@@ -2465,9 +2593,9 @@
 	 */
 	high_output ^= 0x0c;
 
-	BUFFER_ADD = 0x82;
-	BUFFER_ADD = high_output;
-	BUFFER_ADD = high_direction;
+	buffer_write( 0x82 );
+	buffer_write( high_output );
+	buffer_write( high_direction );
 }
 
 
@@ -2485,9 +2613,9 @@
 		high_output = 0x08;
 	}
 
-	BUFFER_ADD = 0x82;
-	BUFFER_ADD = high_output;
-	BUFFER_ADD = high_direction;
+	buffer_write( 0x82 );
+	buffer_write( high_output );
+	buffer_write( high_direction );
 }
 
 
@@ -2646,13 +2774,13 @@
 		}
 
 		/* command "Clock Data to TMS/CS Pin (no Read)" */
-		BUFFER_ADD = 0x4b;
+		buffer_write( 0x4b );
 
 		/* scan 7 bit */
-		BUFFER_ADD = bitcount_per_command - 1;
+		buffer_write( bitcount_per_command - 1 );
 
 		/* TMS data bits are either all zeros or ones to stay in the current stable state */
-		BUFFER_ADD = tms;
+		buffer_write( tms );
 
 		require_send = 1;
 
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to