Hi
I was testing the state move work fronm Dick H. when there were a lot of
changes in the codebase. As you know I keep working from the same base .
There were some problems remaining so I have waited to send the results,
but I hope I found most of them now.
Here comes my patch.
Best regards
Magnus
New jtag statetables in ft2232 and jlink
========================================
The parts concering jtag state tables and transitions are from Dick
Hollenbeck
Some more 7 bit assumptions found in
ft2232_add_scan()
ft2232_read_scan()
In order to work stably with unknown lengths for the last transition out
of SHIFT ft2232,
for IN and IO scans we now always two steps from SCAN -> EXIT1 -> PAUSE,
to collect the final scanbit,
before calling state_move to reach end state. This is the saame
behaviour as in JLink driver
JLink driver has been tweaked and now runs stable. Buffersizes has been
reduced allowing maximum jtag speed
without killing the Linux usb stack.
There is a change from malloc to calloc in jtag.c:jtag_build_buffer()
This removed most weird errors from JLink+ARM7_9 combinations.
Shortest path state moves has been tested with both drivers against
OMAP3530, STM32, ARM926ejs (imx21), LPC2124
Index: src/jtag/jlink.c
===================================================================
--- src/jtag/jlink.c (revision 1606)
+++ src/jtag/jlink.c (working copy)
@@ -44,6 +44,11 @@
#define JLINK_USB_TIMEOUT 1000
// See Section 1.3.2 of the Segger JLink USB protocol manual
+/* 2048 is the max value we can use here */
+//#define JLINK_TAP_BUFFER_SIZE 2048
+#define JLINK_TAP_BUFFER_SIZE 256
+//#define JLINK_TAP_BUFFER_SIZE 384
+
#define JLINK_IN_BUFFER_SIZE 2048
#define JLINK_OUT_BUFFER_SIZE 2*2048+4
#define JLINK_EMU_RESULT_BUFFER_SIZE 64
@@ -57,8 +62,11 @@
#define EMU_CMD_VERSION 0x01
#define EMU_CMD_SET_SPEED 0x05
#define EMU_CMD_GET_STATE 0x07
+#define EMU_CMD_HW_CLOCK 0xc8
+#define EMU_CMD_HW_TMS0 0xc9
+#define EMU_CMD_HW_TMS1 0xca
#define EMU_CMD_HW_JTAG3 0xcf
-#define EMU_CMD_GET_MAX_MEM_BLOCK 0xd4
+#define EMU_CMD_GET_MAX_MEM_BLOCK 0xd4
#define EMU_CMD_HW_RESET0 0xdc
#define EMU_CMD_HW_RESET1 0xdd
#define EMU_CMD_HW_TRST0 0xde
@@ -183,7 +191,7 @@
enum scan_type type;
u8 *buffer;
- DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state);
+ DEBUG_JTAG_IO("scan end in %s", tap_state_name(cmd->cmd.scan->end_state));
if (cmd->cmd.scan->end_state != TAP_INVALID)
jlink_end_state(cmd->cmd.scan->end_state);
@@ -206,10 +214,13 @@
jlink_tap_execute();
- if (cmd->cmd.reset->trst == 1)
+ if ( (cmd->cmd.reset->trst == 1) || ( cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST) ) )
+ {
tap_set_state(TAP_RESET);
+ }
jlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+ jlink_tap_execute();
}
static void jlink_execute_sleep(jtag_command_t *cmd)
@@ -333,6 +344,7 @@
LOG_INFO("J-Link JTAG Interface ready");
jlink_reset(0, 0);
+ jtag_sleep(3000);
jlink_tap_init();
jlink_speed(jtag_speed);
@@ -367,8 +379,9 @@
int i;
int tms = 0;
u8 tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
+ u8 tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
- for (i = 0; i < 7; i++)
+ for (i = 0; i < tms_scan_bits; i++)
{
tms = (tms_scan >> i) & 1;
jlink_tap_append_step(tms, 0);
@@ -409,11 +422,14 @@
tap_state_t saved_end_state = tap_get_end_state();
+ jlink_tap_ensure_space(1,num_cycles + 16);
+
/* only do a state_move when we're not already in IDLE */
if (tap_get_state() != TAP_IDLE)
{
jlink_end_state(TAP_IDLE);
jlink_state_move();
+// num_cycles--;
}
/* execute num_cycles */
@@ -434,7 +450,7 @@
{
tap_state_t saved_end_state;
- jlink_tap_ensure_space(1, scan_size + 8);
+ jlink_tap_ensure_space(1, scan_size + 16);
saved_end_state = tap_get_end_state();
@@ -469,24 +485,23 @@
if (srst == 0)
{
jlink_simple_command(EMU_CMD_HW_RESET1);
- jlink_end_state(TAP_RESET);
- jlink_state_move();
}
- else if (srst == 1)
+ if (srst == 1)
{
jlink_simple_command(EMU_CMD_HW_RESET0);
}
+ if (trst == 1)
+ {
+ jlink_simple_command(EMU_CMD_HW_TRST0);
+ }
if (trst == 0)
{
jlink_simple_command(EMU_CMD_HW_TRST1);
+ jtag_sleep(5000);
jlink_end_state(TAP_RESET);
jlink_state_move();
}
- else if (trst == 1)
- {
- jlink_simple_command(EMU_CMD_HW_TRST0);
- }
}
static void jlink_simple_command(u8 command)
@@ -601,10 +616,8 @@
/***************************************************************************/
/* J-Link tap functions */
-/* 2048 is the max value we can use here */
-#define JLINK_TAP_BUFFER_SIZE 2048
-static unsigned tap_length;
+static unsigned tap_length=0;
static u8 tms_buffer[JLINK_TAP_BUFFER_SIZE];
static u8 tdi_buffer[JLINK_TAP_BUFFER_SIZE];
static u8 tdo_buffer[JLINK_TAP_BUFFER_SIZE];
@@ -631,7 +644,7 @@
static void jlink_tap_ensure_space(int scans, int bits)
{
int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
- int available_bits = JLINK_TAP_BUFFER_SIZE * 8 - tap_length;
+ int available_bits = JLINK_TAP_BUFFER_SIZE * 8 - tap_length - 32;
if (scans > available_scans || bits > available_bits)
{
@@ -646,6 +659,7 @@
if (index >= JLINK_TAP_BUFFER_SIZE)
{
LOG_ERROR("jlink_tap_append_step: overflow");
+ *(u32 *)0xFFFFFFFF = 0;
exit(-1);
}
@@ -654,7 +668,9 @@
// we do not pad TMS, so be sure to initialize all bits
if (0 == bit_index)
+ {
tms_buffer[index] = tdi_buffer[index] = 0;
+ }
if (tms)
tms_buffer[index] |= bit;
@@ -682,8 +698,8 @@
for (i = 0; i < length; i++)
{
- int tms = i < length - 1 ? 0 : 1;
- int tdi = buffer[i / 8] & (1 << (i % 8));
+ int tms = (i < (length - 1)) ? 0 : 1;
+ int tdi = (buffer[i / 8] & (1 << (i % 8)))!=0;
jlink_tap_append_step(tms, tdi);
}
pending_scan_results_length++;
@@ -700,6 +716,13 @@
if (!tap_length)
return ERROR_OK;
+ /* JLink returns an extra NULL in packet when size of in message is a multiple of 64, creates problems with usb comms */
+ /* WARNING This will interfere with tap state counting */
+ while ((TAP_SCAN_BYTES(tap_length)%64)==0)
+ {
+ jlink_tap_append_step((tap_get_state() == TAP_RESET)?1:0, 0);
+ }
+
// number of full bytes (plus one if some would be left over)
byte_length = TAP_SCAN_BYTES(tap_length);
@@ -839,9 +862,15 @@
result2 = jlink_usb_read_emu_result(jlink_jtag);
if (1 != result2)
{
- LOG_ERROR("jlink_usb_read_emu_result failed "
- "(requested=1, result=%d)", result2);
- return ERROR_JTAG_DEVICE_ERROR;
+ LOG_ERROR("jlink_usb_read_emu_result retried requested=1, result=%d, in_length=%i", result2,in_length);
+ /* Try again once, should only happen if (in_length%64==0) */
+ result2 = jlink_usb_read_emu_result(jlink_jtag);
+ if (1 != result2)
+ {
+ LOG_ERROR("jlink_usb_read_emu_result failed "
+ "(requested=1, result=%d)", result2);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
}
/* Check the result itself */
@@ -975,3 +1004,4 @@
}
}
#endif
+
Index: src/jtag/ft2232.c
===================================================================
--- src/jtag/ft2232.c (revision 1606)
+++ src/jtag/ft2232.c (working copy)
@@ -5,6 +5,9 @@
* Copyright (C) 2008 by Spencer Oliver *
* [email protected] *
* *
+* Copyright (C) 2009 by SoftPLC Corporation. http://softplc.com *
+* Dick Hollenbeck <[email protected]> *
+* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
@@ -26,6 +29,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 +56,14 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <assert.h>
+#if (BUILD_FT2232_FTD2XX==1 && BUILD_FT2232_LIBFTDI==1)
+#error "BUILD_FT2232_FTD2XX && BUILD_FT2232_LIBFTDI are mutually exclusive"
+#elif(BUILD_FT2232_FTD2XX!=1 && BUILD_FT2232_LIBFTDI!=1)
+#error "BUILD_FT2232_FTD2XX || BUILD_FT2232_LIBFTDI must be chosen"
+#endif
+
/* FT2232 access library includes */
#if BUILD_FT2232_FTD2XX == 1
#include <ftd2xx.h>
@@ -58,6 +71,9 @@
#include <ftdi.h>
#endif
+/* max TCK for the high speed devices 30000 kHz */
+#define FTDI_2232H_4232H_MAX_TCK 30000
+
static int ft2232_execute_queue(void);
static int ft2232_speed(int speed);
@@ -85,12 +101,14 @@
static int ft2232_stableclocks(int num_cycles, jtag_command_t* cmd);
-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 char * ft2232_device_desc_A = NULL;
+static char* ft2232_device_desc = NULL;
+static char* ft2232_serial = NULL;
+static char* ft2232_layout = NULL;
+static u8 ft2232_latency = 2;
+static unsigned ft2232_max_tck = 6000;
+
#define MAX_USB_IDS 8
/* vid = pid = 0 marks the end of the list */
static u16 ft2232_vid[MAX_USB_IDS + 1] = { 0x0403, 0 };
@@ -112,9 +130,9 @@
static int turtle_init(void);
static int comstick_init(void);
static int stm32stick_init(void);
-static int axm0432_jtag_init(void);
-static int sheevaplug_init(void);
-static int icebear_jtag_init(void);
+static int axm0432_jtag_init(void);
+static int sheevaplug_init(void);
+static int icebear_jtag_init(void);
/* reset procedures for supported layouts */
static void usbjtag_reset(int trst, int srst);
@@ -133,7 +151,7 @@
static void flyswatter_jtag_blink(void);
static void turtle_jtag_blink(void);
-ft2232_layout_t ft2232_layouts[] =
+ft2232_layout_t ft2232_layouts[] =
{
{ "usbjtag", usbjtag_init, usbjtag_reset, NULL },
{ "jtagkey", jtagkey_init, jtagkey_reset, NULL },
@@ -161,7 +179,7 @@
static u8 high_direction = 0x0;
#if BUILD_FT2232_FTD2XX == 1
-static FT_HANDLE ftdih = NULL;
+static FT_HANDLE ftdih = NULL;
#elif BUILD_FT2232_LIBFTDI == 1
static struct ftdi_context ftdic;
#endif
@@ -170,15 +188,143 @@
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( ft2232_buffer );
+ 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_buffer );
+ assert( ft2232_read_pointer < ft2232_buffer_size );
+ return ft2232_buffer[ft2232_read_pointer++];
+}
+
+
+/**
+ * Function clock_tms
+ * 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.
+ * Rigorous state transition logging is done here via tap_set_state().
+ *
+ * @param pmsse_cmd is one of the MPSSE TMS oriented commands such as 0x4b or 0x6b. See
+ * the MPSSE spec referenced above for their functionality. The MPSSE command
+ * "Clock Data to TMS/CS Pin (no Read)" is often used for this, 0x4b.
+ *
+ * @param tms_bits holds the sequence of bits to send.
+ * @param tms_count tells how many bits in the sequence.
+ * @param tdi_bit is a single bit which is passed on to TDI before the first TCK cycle
+ * and is held static for the duration of TMS clocking. See the MPSSE spec referenced above.
+ */
+static void clock_tms( u8 mpsse_cmd, int tms_bits, int tms_count, bool tdi_bit )
+{
+ u8 tms_byte;
+ int i;
+ int tms_ndx; /* bit index into tms_byte */
+
+ assert( tms_count > 0 );
+
+// LOG_DEBUG("mpsse cmd=%02x, tms_bits=0x%08x, bit_count=%d", mpsse_cmd, tms_bits, tms_count );
+
+ for (tms_byte = tms_ndx = i = 0; i < tms_count; ++i, tms_bits>>=1)
+ {
+ bool bit = tms_bits & 1;
+
+ if(bit)
+ tms_byte |= (1<<tms_ndx);
+
+ /* always do state transitions in public view */
+ tap_set_state( tap_state_transition(tap_get_state(), bit) );
+
+ /* we wrote a bit to tms_byte just above, increment bit index. if bit was zero
+ also increment.
+ */
+ ++tms_ndx;
+
+ if( tms_ndx==7 || i==tms_count-1 )
+ {
+ buffer_write( mpsse_cmd );
+ buffer_write( tms_ndx - 1 );
+
+ /* Bit 7 of the byte is passed on to TDI/DO before the first TCK/SK of
+ TMS/CS and is held static for the duration of TMS/CS clocking.
+ */
+ buffer_write( tms_byte | (tdi_bit << 7) );
+ }
+ }
+}
+
+
+/**
+ * Function get_tms_buffer_requirements
+ * returns what clock_tms() will consume if called with
+ * same \a bit_count.
+ */
+static inline int get_tms_buffer_requirements( int bit_count )
+{
+ return ((bit_count + 6)/7) * 3;
+}
+
+
+/**
+ * Function move_to_state
+ * moves the TAP controller from the current state to a
+ * \a goal_state through a path given by tap_get_tms_path(). State transition
+ * logging is performed by delegation to clock_tms().
+ *
+ * @param goal_state is the destination state for the move.
+ */
+static void move_to_state( tap_state_t goal_state )
+{
+ tap_state_t start_state = tap_get_state();
+
+ /* goal_state is 1/2 of a tuple/pair of states which allow convenient
+ lookup of the required TMS pattern to move to this state from the
+ start state.
+ */
+
+ /* do the 2 lookups */
+ int tms_bits = tap_get_tms_path(start_state, goal_state);
+ int tms_count = tap_get_tms_path_len(start_state, goal_state);
+
+ DEBUG_JTAG_IO( "start=%s goal=%s", tap_state_name(start_state), tap_state_name(goal_state) );
+
+ clock_tms( 0x4b, tms_bits, tms_count, 0 );
+}
+
+
jtag_interface_t ft2232_interface =
{
.name = "ft2232",
@@ -195,7 +341,7 @@
{
#if BUILD_FT2232_FTD2XX == 1
FT_STATUS status;
- DWORD dw_bytes_written;
+ DWORD dw_bytes_written;
if ( ( status = FT_Write(ftdih, buf, size, &dw_bytes_written) ) != FT_OK )
{
*bytes_written = dw_bytes_written;
@@ -278,7 +424,7 @@
int retval;
u32 bytes_written;
- buf[0] = 0x86; /* command "set divisor" */
+ buf[0] = 0x86; /* command "set divisor" */
buf[1] = speed & 0xff; /* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/
buf[2] = (speed >> 8) & 0xff; /* valueH */
@@ -299,7 +445,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;
}
@@ -320,9 +466,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;
@@ -368,7 +514,7 @@
tap_set_end_state(state);
else
{
- LOG_ERROR("BUG: %i is not a valid end state", state);
+ LOG_ERROR("BUG: %s is not a stable end state", tap_state_name(state));
exit(-1);
}
}
@@ -382,19 +528,19 @@
while (num_bytes-- > 1)
{
- buffer[cur_byte] = BUFFER_READ;
- cur_byte++;
+ buffer[cur_byte++] = buffer_read();
bits_left -= 8;
}
buffer[cur_byte] = 0x0;
+ /* There is one more partial byte left from the clock data in/out instructions */
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);
+ /* This shift depends on the length of the clock data to tms instruction, insterted at end of the scan, now fixed to a two step transition in ft2232_add_scan */
+ buffer[cur_byte] = ( buffer[cur_byte] | ( ( (buffer_read()) << 1 ) & 0x80 )) >> (8 - bits_left);
}
@@ -538,46 +684,44 @@
}
-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;
+ tap_state_t walker = tap_get_state();
- 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;
-
- int num_states_batch = num_states > 7 ? 7 : num_states;
-
- /* command "Clock Data to TMS/CS Pin (no Read)" */
- BUFFER_ADD = 0x4b;
-
- /* number of states remaining */
- BUFFER_ADD = num_states_batch - 1;
-
- while (num_states_batch--)
+ if (tap_state_transition(walker, false) == desired_next_state )
+ ; /* bit within tms_bits at index state_ndx is already zero */
+ else if (tap_state_transition(walker, true) == desired_next_state )
+ tms_bits |= (1<<state_ndx);
+ else
{
- 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--;
+ LOG_ERROR( "BUG: %s -> %s isn't a valid TAP transition",
+ tap_state_name(walker), tap_state_name(desired_next_state) );
+ exit(-1);
}
- BUFFER_ADD = tms_byte;
+ walker = desired_next_state;
}
-
+
+ clock_tms( 0x4b, tms_bits, num_states, 0 );
+
tap_set_end_state(tap_get_state());
}
@@ -589,26 +733,19 @@
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);
+ move_to_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);
+ move_to_state( TAP_IRSHIFT );
}
- /* LOG_DEBUG("added TMS scan (no read)"); */
}
/* add command for complete bytes */
@@ -618,34 +755,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];
- cur_byte++;
+ buffer_write( buffer[cur_byte++] );
bits_left -= 8;
}
}
@@ -667,24 +804,25 @@
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) )
@@ -693,44 +831,57 @@
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
{
+ int tms_bits;
+ int tms_count;
+ u8 mpsse_cmd;
+
/* move from Shift-IR/DR to end state */
if (type != SCAN_OUT)
{
+ /* We always go to the PAUSE state in two step at the end of an IN or IO scan */
+ /* This must be coordinated with the bit shifts in ft2232_read_scan */
+ tms_bits = 0x01;
+ tms_count = 2;
/* Clock Data to TMS/CS Pin with Read */
- BUFFER_ADD = 0x6b;
+ mpsse_cmd = 0x6b;
/* LOG_DEBUG("added TMS scan (read)"); */
}
else
{
+ tms_bits = tap_get_tms_path( tap_get_state(), tap_get_end_state() );
+ tms_count = tap_get_tms_path_len( tap_get_state(), tap_get_end_state() );
/* Clock Data to TMS/CS Pin (no Read) */
- BUFFER_ADD = 0x4b;
+ mpsse_cmd = 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);
- tap_set_state( tap_get_end_state() );
+ clock_tms( mpsse_cmd, tms_bits, tms_count, last_bit );
}
+
+ if (tap_get_state() != tap_get_end_state())
+ {
+ move_to_state( tap_get_end_state() );
+ }
}
@@ -755,14 +906,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);
+ move_to_state( TAP_DRSHIFT );
}
if ( ( retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written) ) != ERROR_OK )
@@ -781,34 +925,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;
}
@@ -852,24 +996,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;
@@ -880,42 +1024,45 @@
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
{
+ int tms_bits = tap_get_tms_path( tap_get_state(), tap_get_end_state() );
+ int tms_count = tap_get_tms_path_len( tap_get_state(), tap_get_end_state() );
+ u8 mpsse_cmd;
+
/* move from Shift-IR/DR to end state */
if (type != SCAN_OUT)
{
/* Clock Data to TMS/CS Pin with Read */
- BUFFER_ADD = 0x6b;
+ mpsse_cmd = 0x6b;
/* LOG_DEBUG("added TMS scan (read)"); */
}
else
{
/* Clock Data to TMS/CS Pin (no Read) */
- BUFFER_ADD = 0x4b;
+ mpsse_cmd = 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);
- tap_set_state( tap_get_end_state() );
+
+ clock_tms( mpsse_cmd, tms_bits, tms_count, last_bit );
}
if (type != SCAN_OUT)
@@ -950,12 +1097,13 @@
int num_bytes = (scan_size - 1) / 8;
if (tap_get_state() != TAP_DRSHIFT)
- predicted_size += 3;
+ predicted_size += get_tms_buffer_requirements( tap_get_tms_path_len( tap_get_state(), TAP_DRSHIFT) );
if (type == SCAN_IN) /* only from device to host */
{
/* complete bytes */
predicted_size += CEIL(num_bytes, 65536) * 3;
+
/* remaining bits - 1 (up to 7) */
predicted_size += ( (scan_size - 1) % 8 ) ? 2 : 0;
}
@@ -963,6 +1111,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;
}
@@ -1026,9 +1175,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 );
}
@@ -1065,9 +1214,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);
}
@@ -1100,9 +1249,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);
}
@@ -1130,9 +1279,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);
}
@@ -1159,9 +1308,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);
}
@@ -1180,9 +1329,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);
}
@@ -1208,9 +1357,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);
}
@@ -1237,14 +1386,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);
}
@@ -1264,9 +1413,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);
}
@@ -1275,7 +1424,7 @@
int retval;
retval = ERROR_OK;
- DEBUG_JTAG_IO("end_state: %i", cmd->cmd.end_state->end_state);
+ DEBUG_JTAG_IO("execute_end_state: %s", tap_state_name(cmd->cmd.end_state->end_state) );
if (cmd->cmd.end_state->end_state != TAP_INVALID)
ft2232_end_state(cmd->cmd.end_state->end_state);
@@ -1291,9 +1440,10 @@
int predicted_size = 0;
retval = ERROR_OK;
- DEBUG_JTAG_IO("runtest %i cycles, end in %i",
+ DEBUG_JTAG_IO("runtest %i cycles, end in %s",
cmd->cmd.runtest->num_cycles,
- cmd->cmd.runtest->end_state);
+ tap_state_name(cmd->cmd.runtest->end_state));
+
/* only send the maximum buffer size that FT2232C can handle */
predicted_size = 0;
if (tap_get_state() != TAP_IDLE)
@@ -1312,27 +1462,24 @@
}
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);
+ move_to_state( TAP_IDLE );
require_send = 1;
}
i = cmd->cmd.runtest->num_cycles;
while (i > 0)
{
+ /* there are no state transitions in this code, so omit state tracking */
+
/* 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)"); */
}
@@ -1342,15 +1489,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)"); */
+ move_to_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() ) );
@@ -1359,11 +1500,11 @@
return retval;
}
+
static int ft2232_execute_statemove(jtag_command_t *cmd)
{
- int retval;
- int predicted_size = 0;
- retval = ERROR_OK;
+ int predicted_size = 0;
+ int retval = ERROR_OK;
DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
@@ -1379,61 +1520,60 @@
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 */
+ if ( tap_get_state() != tap_get_end_state() )
+ {
+ move_to_state( tap_get_end_state() );
+ require_send = 1;
+ }
- 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;
}
static int ft2232_execute_pathmove(jtag_command_t *cmd)
{
- int retval;
- int predicted_size = 0;
- retval = ERROR_OK;
+ int predicted_size = 0;
+ int retval = ERROR_OK;
- DEBUG_JTAG_IO("pathmove: %i states, end in %i",
- cmd->cmd.pathmove->num_states,
- cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
+ tap_state_t* path = cmd->cmd.pathmove->path;
+ int num_states = cmd->cmd.pathmove->num_states;
+
+ DEBUG_JTAG_IO("pathmove: %i states, current: %s end: %s", num_states,
+ tap_state_name( tap_get_state() ),
+ tap_state_name( path[num_states-1] )
+ );
+
/* only send the maximum buffer size that FT2232C can handle */
- predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);
+ predicted_size = 3 * CEIL(num_states, 7);
if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{
if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
+ retval = ERROR_JTAG_QUEUE_FAILED;
+
require_send = 0;
first_unsent = cmd;
}
- ft2232_add_pathmove(cmd->cmd.pathmove);
+
+ ft2232_add_pathmove( path, num_states );
require_send = 1;
-#ifdef _DEBUG_JTAG_IO_
- LOG_DEBUG( "pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states,
- tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]) );
-#endif
+
return retval;
}
+
static int ft2232_execute_scan(jtag_command_t *cmd)
{
- int retval;
u8* buffer;
int scan_size; /* size of IR or DR scan */
- enum scan_type type;
int predicted_size = 0;
- retval = ERROR_OK;
+ int retval = ERROR_OK;
+ enum scan_type type = jtag_scan_type(cmd->cmd.scan);
+
+ DEBUG_JTAG_IO( "%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN", type );
+
scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
- type = jtag_scan_type(cmd->cmd.scan);
+
predicted_size = ft2232_predict_scan_out(scan_size, type);
if ( (predicted_size + 1) > FT2232_BUFFER_SIZE )
{
@@ -1553,17 +1693,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;
}
@@ -1613,10 +1753,10 @@
#if BUILD_FT2232_FTD2XX == 1
static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int* try_more)
{
- FT_STATUS status;
- DWORD openex_flags = 0;
- char* openex_string = NULL;
- u8 latency_timer;
+ FT_STATUS status;
+ DWORD openex_flags = 0;
+ char* openex_string = NULL;
+ u8 latency_timer;
LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)", ft2232_layout, vid, pid);
@@ -1775,6 +1915,12 @@
if (ftdi_init(&ftdic) < 0)
return ERROR_JTAG_INIT_FAILED;
+ if (ftdi_set_interface(&ftdic, INTERFACE_A) < 0)
+ {
+ LOG_ERROR("unable to select FT2232 channel A: %s", ftdic.error_str);
+ return ERROR_JTAG_INIT_FAILED;
+ }
+
/* context, vendor id, product id */
if (ftdi_usb_open_desc(&ftdic, vid, pid, ft2232_device_desc,
ft2232_serial) < 0)
@@ -1788,12 +1934,7 @@
return ERROR_JTAG_INIT_FAILED;
}
- if (ftdi_set_interface(&ftdic, INTERFACE_A) < 0)
- {
- LOG_ERROR("unable to select FT2232 channel A: %s", ftdic.error_str);
- return ERROR_JTAG_INIT_FAILED;
- }
-
+ /* There is already a rest in ftdi_usb_open_desc, this should be redundant */
if (ftdi_usb_reset(&ftdic) < 0)
{
LOG_ERROR("unable to reset ftdi device");
@@ -1844,6 +1985,15 @@
ft2232_layout_t* cur_layout = ft2232_layouts;
int i;
+ if (tap_get_tms_path_len(TAP_IRPAUSE,TAP_IRPAUSE)==7)
+ {
+ LOG_DEBUG("ft2232 interface using 7 step jtag state transitions");
+ }
+ else
+ {
+ LOG_DEBUG("ft2232 interface using shortest path jtag state transitions");
+
+ }
if ( (ft2232_layout == NULL) || (ft2232_layout[0] == 0) )
{
ft2232_layout = "usbjtag";
@@ -2404,7 +2554,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;
}
@@ -2432,7 +2582,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;
}
@@ -2455,9 +2605,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 );
}
@@ -2468,9 +2618,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 );
}
@@ -2488,9 +2638,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 );
}
@@ -2648,14 +2798,16 @@
first_unsent = cmd;
}
+ /* there are no state transitions in this code, so omit state tracking */
+
/* 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;
@@ -2665,6 +2817,7 @@
return retval;
}
+
/* ---------------------------------------------------------------------
* Support for IceBear JTAG adapter from Section5:
* http://section5.ch/icebear
@@ -2761,8 +2914,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);
}
Index: src/jtag/jtag.c
===================================================================
--- src/jtag/jtag.c (revision 1606)
+++ src/jtag/jtag.c (working copy)
@@ -769,6 +769,9 @@
#endif
}
}
+
+ /* field_count represents the true number of fields setup*/
+ (*last_cmd)->cmd.scan->num_fields = field_count;
return ERROR_OK;
}
@@ -1243,7 +1246,7 @@
int i;
bit_count = jtag_scan_size(cmd);
- *buffer = malloc(CEIL(bit_count, 8));
+ *buffer = calloc(1,CEIL(bit_count, 8));
bit_count = 0;
@@ -3127,7 +3130,7 @@
#define B8(bits,count) { ((u8)B8__(HEX__(bits))), (count) }
-#if 0 && ((BUILD_FT2232_FTD2XX==1) || (BUILD_FT2232_LIBFTDI==1))
+#if 1 && ((BUILD_FT2232_FTD2XX==1) || (BUILD_FT2232_LIBFTDI==1) || (BUILD_JLINK==1))
/* this is the table submitted by Jeff Williams on 3/30/2009 with this comment:
OK, I added Peter's version of the state table, and it works OK for
@@ -3142,13 +3145,13 @@
*/
/* to state: */
- /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
- { B8(11111,5), B8(0,1), B8(0010,4), B8(01010,5), B8(00110,5), B8(010110,6) }, /* RESET */
- { B8(11111,5), B8(0,1), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */
- { B8(11111,5), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */
- { B8(11111,5), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */
- { B8(11111,5), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */
- { B8(11111,5), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1) } /* IRPAUSE */
+ /* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
+ { B8(1111111,7), B8(0000000,7), B8(00101,5), B8(01010,5), B8(001101,6), B8(010110,6) }, /* RESET */
+ { B8(1111111,7), B8(0000000,7), B8(001,3), B8(0101,4), B8(0011,4), B8(01011,5) }, /* IDLE */
+ { B8(1111111,7), B8(011,3), B8(00111,5), B8(01,2), B8(001111,6), B8(0101111,7) }, /* DRSHIFT */
+ { B8(1111111,7), B8(011,3), B8(01,2), B8(0,1), B8(001111,6), B8(0101111,7) }, /* DRPAUSE */
+ { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(001111,6), B8(01,2) }, /* IRSHIFT */
+ { B8(1111111,7), B8(011,3), B8(00111,5), B8(010111,6), B8(01,2), B8(0,1) } /* IRPAUSE */
#else /* this is the old table, converted from hex and with the bit_count set to 7 for each combo, like before */
@@ -3159,7 +3162,7 @@
{ B8(1111111,7), B8(0110001,7), B8(0000000,7), B8(0000001,7), B8(0001111,7), B8(0101111,7) }, /* DRSHIFT */
{ B8(1111111,7), B8(0110000,7), B8(0100000,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* DRPAUSE */
{ B8(1111111,7), B8(0110001,7), B8(0000111,7), B8(0010111,7), B8(0000000,7), B8(0000001,7) }, /* IRSHIFT */
- { B8(1111111,7), B8(0110000,7), B8(0011100,7), B8(0010111,7), B8(0100000,7), B8(0101111,7) }, /* IRPAUSE */
+ { B8(1111111,7), B8(0110000,7), B8(0011100,7), B8(0010111,7), B8(0011110,7), B8(0101111,7) }, /* IRPAUSE */
#endif
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development