Dick Hollenbeck <dick@softplc.com> and Jeff Williams tap_get_tms_path_len()

git-svn-id: svn://svn.berlios.de/openocd/trunk@1557 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
oharboe 2009-04-28 19:02:29 +00:00
parent f1864e3e92
commit abeee8b4c2
2 changed files with 127 additions and 45 deletions

View File

@ -1245,7 +1245,7 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer)
bit_count = 0;
#ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("num_fields: %i",cmd->num_fields);
LOG_DEBUG("%s num_fields: %i", cmd->ir_scan ? "IRSCAN" : "DRSCAN", cmd->num_fields);
#endif
for (i = 0; i < cmd->num_fields; i++)
@ -1261,10 +1261,20 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer)
free(char_buf);
#endif
}
else
{
#ifdef _DEBUG_JTAG_IO_
LOG_DEBUG("fields[%i].out_value[%i]: NULL", i, cmd->fields[i].num_bits);
#endif
}
bit_count += cmd->fields[i].num_bits;
}
#ifdef _DEBUG_JTAG_IO_
//LOG_DEBUG("bit_count totalling: %i", bit_count );
#endif
return bit_count;
}
@ -3053,14 +3063,6 @@ int tap_move_ndx( tap_state_t astate )
{
/* given a stable state, return the index into the tms_seqs[] array within tap_get_tms_path() */
/* old version
const static int move_map[16] =
{
0, -1, -1, 2, -1, 3, -1, -1,
1, -1, -1, 4, -1, 5, -1, -1
};
*/
int ndx;
switch( astate )
@ -3079,45 +3081,106 @@ int tap_move_ndx( tap_state_t astate )
return ndx;
}
/* tap_move[i][j]: tap movement command to go from state i to state j
* 0: Test-Logic-Reset
* 1: Run-Test/Idle
* 2: Shift-DR
* 3: Pause-DR
* 4: Shift-IR
* 5: Pause-IR
*
* DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code
*/
static struct
{
u8 bits;
u8 bit_count;
} tms_seqs[6][6] = /* [from_state_ndx][to_state_ndx] */
{
/* value clocked to TMS to move from one of six stable states to another.
* N.B. OOCD clocks TMS from LSB first, so read these right-to-left.
* N.B. These values are tightly bound to the table in tap_get_tms_path_len().
* N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable.
* These extra ones cause no TAP state problem, because we go into reset and stay in reset.
*/
/*
* These macros allow us to specify TMS state transitions by bits rather than hex bytes.
* Read the bits from LSBit first to MSBit last (right-to-left).
*/
#define HEX__(n) 0x##n##LU
#define B8__(x) \
(((x) & 0x0000000FLU)?(1<<0):0) \
+(((x) & 0x000000F0LU)?(1<<1):0) \
+(((x) & 0x00000F00LU)?(1<<2):0) \
+(((x) & 0x0000F000LU)?(1<<3):0) \
+(((x) & 0x000F0000LU)?(1<<4):0) \
+(((x) & 0x00F00000LU)?(1<<5):0) \
+(((x) & 0x0F000000LU)?(1<<6):0) \
+(((x) & 0xF0000000LU)?(1<<7):0)
#define B8(bits,count) { ((u8)B8__(HEX__(bits))), (count) }
#if 0 && ((BUILD_FT2232_FTD2XX==1) || (BUILD_FT2232_LIBFTDI==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
me on MC1322x. I've recreated the jlink portion of patch with this
new state table. His changes to my state table are pretty minor in
terms of total transitions, but Peter feels that his version fixes
some long-standing problems.
Jeff
I added the bit count into the table
Dick
*/
/* 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 */
#else /* this is the old table, converted from hex and with the bit_count set to 7 for each combo, like before */
/* to state: */
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */ /* from state: */
{ B8(1111111,7), B8(0000000,7), B8(0010111,7), B8(0001010,7), B8(0011011,7), B8(0010110,7) }, /* RESET */
{ B8(1111111,7), B8(0000000,7), B8(0100101,7), B8(0000101,7), B8(0101011,7), B8(0001011,7) }, /* IDLE */
{ 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 */
#endif
#if 0 /* keeping old hex stuff for awhile, for reference */
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */
{ 0x7f, 0x00, 0x17, 0x0a, 0x1b, 0x16 }, /* RESET */
{ 0x7f, 0x00, 0x25, 0x05, 0x2b, 0x0b }, /* IDLE */
{ 0x7f, 0x31, 0x00, 0x01, 0x0f, 0x2f }, /* DRSHIFT */
{ 0x7f, 0x30, 0x20, 0x17, 0x1e, 0x2f }, /* DRPAUSE */
{ 0x7f, 0x31, 0x07, 0x17, 0x00, 0x01 }, /* IRSHIFT */
{ 0x7f, 0x30, 0x1c, 0x17, 0x20, 0x2f } /* IRPAUSE */
#endif
};
int tap_get_tms_path( tap_state_t from, tap_state_t to )
{
/* tap_move[i][j]: tap movement command to go from state i to state j
* 0: Test-Logic-Reset
* 1: Run-Test/Idle
* 2: Shift-DR
* 3: Pause-DR
* 4: Shift-IR
* 5: Pause-IR
*
* DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code
*/
static const u8 tms_seqs[6][6] =
{
/* value clocked to TMS to move from one of six stable states to another */
return tms_seqs[tap_move_ndx(from)][tap_move_ndx(to)].bits;
}
/* RESET IDLE DRSHIFT DRPAUSE IRSHIFT IRPAUSE */
{ 0x7f, 0x00, 0x17, 0x0a, 0x1b, 0x16 }, /* RESET */
{ 0x7f, 0x00, 0x25, 0x05, 0x2b, 0x0b }, /* IDLE */
{ 0x7f, 0x31, 0x00, 0x01, 0x0f, 0x2f }, /* DRSHIFT */
{ 0x7f, 0x30, 0x20, 0x17, 0x1e, 0x2f }, /* DRPAUSE */
{ 0x7f, 0x31, 0x07, 0x17, 0x00, 0x01 }, /* IRSHIFT */
{ 0x7f, 0x30, 0x1c, 0x17, 0x20, 0x2f } /* IRPAUSE */
};
if( !tap_is_state_stable(from) )
{
LOG_ERROR( "fatal: tap_state \"from\" (=%s) is not stable", tap_state_name(from) );
exit(1);
}
if( !tap_is_state_stable(to) )
{
LOG_ERROR( "fatal: tap_state \"to\" (=%s) is not stable", tap_state_name(to) );
exit(1);
}
/* @todo: support other than 7 clocks ? */
return tms_seqs[tap_move_ndx(from)][tap_move_ndx(to)];
int tap_get_tms_path_len( tap_state_t from, tap_state_t to )
{
return tms_seqs[tap_move_ndx(from)][tap_move_ndx(to)].bit_count;
}
@ -3250,7 +3313,7 @@ const char* tap_state_name(tap_state_t state)
switch( state )
{
case TAP_RESET: ret = "RESET"; break;
case TAP_IDLE: ret = "RUN/IDLE"; break;
case TAP_IDLE: ret = "RUN/IDLE"; break;
case TAP_DRSELECT: ret = "DRSELECT"; break;
case TAP_DRCAPTURE: ret = "DRCAPTURE"; break;
case TAP_DRSHIFT: ret = "DRSHIFT"; break;

View File

@ -181,6 +181,25 @@ tap_state_t tap_get_end_state(void);
*/
int tap_get_tms_path(tap_state_t from, tap_state_t to);
/**
* Function int tap_get_tms_path_len
* returns the total number of bits that represents a TMS path
* transition as given by the function tap_get_tms_path().
*
* For at least one interface (JLink) it's not OK to simply "pad" TMS sequences
* to fit a whole byte. (I suspect this is a general TAP problem within OOCD.)
* Padding TMS causes all manner of instability that's not easily
* discovered. Using this routine we can apply EXACTLY the state transitions
* required to make something work - no more - no less.
*
* @param from is the starting state
* @param to is the resultant or final state
* @return int - the total number of bits in a transition.
*/
int tap_get_tms_path_len(tap_state_t from, tap_state_t to);
/**
* Function tap_move_ndx
* when given a stable state, returns an index from 0-5. The index corresponds to a