Rick Altherr wrote:
There are currently problems that possibly prevent the OpenOCD from
adding
the DAP.
1) When performing ir/dr scans the default end state is Run Test Idle.
This does not match
what the ICEPICK wants. I don't know it this is a problem or not
I know that the JTAG internals in OpenOCD can support this. It may be
as simple as allowing an extra argument to the irscan and drscan
commands in the TCL layer.
2) The tap_move that allows moving between "stable" tap states does
not follow "shortest pad"
but always takes 7 steps, possibly passing via test logic reset. I
mailed about it
https://lists.berlios.de/pipermail/openocd-development/2009-February/004625.html
Yes. I remember seeing the query about this, but I didn't realize it
was a limiting issue for ICEPICK.
3) There is no support for generating clock pulses in the IDLE state.
but this is required
The internals have support for this as it was needed for SVF support.
Again, it may just need to be exposed at the TCL layer.
It is my understanding that we need 1, 2 and 3 fixed/improved to get
OMAP3 (ARM) access with OpenOCD. Correct?
Are there already any patches, proposals or e.g. pseudo code available
for these three topics?
Not currently.
Being not so familiar with OpenOCD code,
something like this would help as a starting point. Strings like "need
to be exposed at the TCL layer"
That means that a call to register_command needs to be made so that the
TCL interpreter knows that the new command exists and what C function to
call when it is executed. For #3, a new C function needs to be added
that parses the arguments and calls the JTAG method for clocking in
idle. I think run_test may already do that.
or "extra argument to the irscan and
drscan commands in the TCL layer"
This just means that the C function for the irscan and drscan commands
needs to look for another argument (namely the end state) and add a call
to jtag_set_end_state. This might also be handled already with a
'end_state' command.
Ah, yes. Understood.
Looking at jtag.c and irscan/drscan implementations:
Why is irscan implemented as handle_irscan_command(), but drscan as
Jim_Command_drscan()? What is the difference between handle_xx_command
and Jim_command_xx?
Additionally, short status update from me:
As pointed out by Kees [1], the 'do always 7 clocks
tap_get_tms_path()' might not be flexible enough for OMAP. So I played
a little with Holger's jtag_move_to() [2] and used it to hack a new
tap_get_tms_path() (see patch in attachment for recent status).
Unfortunately, this doesn't work correctly yet:
Adding some debugging output to original version of OpenOCD and the
hacked one with 'new' tap_get_tms_path() I get the output below. Have
to investigate why new version fails with 'Could not validate end ...'.
And, I wonder why the new version needs ~6 initial TAP_RESET moves as
marked with OMAP3_HACK in patch in attachment. Else, the ID code won't
be detected correctly. I assume that this isn't related to new
tap_get_tms_path(). I vote for a reset issue (?)
Best regards
Dirk
[1]
https://lists.berlios.de/pipermail/openocd-development/2009-February/004773.html
[2]
https://lists.berlios.de/pipermail/openocd-development/2009-February/004736.html
Output of original OpenOCD version with some additional debug output.
This is the 'do always 7 clocks version':
-- cut --
...
$URL: svn://svn.berlios.de/openocd/trunk/src/openocd.c $
jtag_speed: 1
jtag move from RESET to RESET
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
jtag move from RESET to DRSHIFT
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 0, advance to IDLE 8
tms 1, advance to DRSELECT 1
tms 0, advance to DRCAPTURE 2
tms 0, advance to DRSHIFT 3
jtag move from DRSHIFT to RESET
tms 1, advance to DREXIT1 4
tms 1, advance to DRUPDATE 7
tms 1, advance to DRSELECT 1
tms 1, advance to IRSELECT 9
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
Info : JTAG tap: omap3530.jrc tap/device found: 0x0b7ae02f
(Manufacturer: 0x017, Part: 0xb7ae, Version: 0x0)
Info : JTAG Tap/device matched
Total ir length: 8
jtag move from RESET to IRSHIFT
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 0, advance to IDLE 8
tms 1, advance to DRSELECT 1
tms 1, advance to IRSELECT 9
tms 0, advance to IRCAPTURE 10
tms 0, advance to IRSHIFT 11
jtag move from IRSHIFT to RESET
tms 1, advance to IREXIT1 12
tms 1, advance to IRUPDATE 15
tms 1, advance to DRSELECT 1
tms 1, advance to IRSELECT 9
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
Chain pos: 6, ir_test: 0x000000c1
...
-- cut --
Output of modified OpenOCD:
-- cut --
...
$URL: svn://svn.berlios.de/openocd/trunk/src/openocd.c $
jtag_speed: 1
jtag move from RESET to RESET
tms 1, advance to RESET 0
tms 1, advance to RESET 0 <=== If here are < ~6 moves ID code
isn't detected???
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
tms 1, advance to RESET 0
jtag move from RESET to DRSHIFT
tms 0, advance to IDLE 8
tms 1, advance to DRSELECT 1
tms 0, advance to DRCAPTURE 2
tms 0, advance to DRSHIFT 3
jtag move from DRSHIFT to RESET
tms 1, advance to DREXIT1 4
tms 1, advance to DRUPDATE 7
tms 1, advance to DRSELECT 1
tms 1, advance to IRSELECT 9
tms 1, advance to RESET 0
Info : JTAG tap: omap3530.jrc tap/device found: 0x0b7ae02f
(Manufacturer: 0x017, Part: 0xb7ae, Version: 0x0)
Info : JTAG Tap/device matched
Total ir length: 8
jtag move from RESET to IRSHIFT
tms 0, advance to IDLE 8
tms 1, advance to DRSELECT 1
tms 1, advance to IRSELECT 9
tms 0, advance to IRCAPTURE 10
tms 0, advance to IRSHIFT 11
jtag move from IRSHIFT to RESET
tms 1, advance to IREXIT1 12
tms 1, advance to IRUPDATE 15
tms 1, advance to DRSELECT 1
tms 1, advance to IRSELECT 9
tms 1, advance to RESET 0
Chain pos: 6, ir_test: 0x00000041
Error: Could not validate end of JTAG scan chain, IR mismatch, scan
returned 0x41. pos=6 expected 0x3 got 1
Warn : Could not validate JTAG chain, continuing anyway...
...
-- cut --
Signed-off-by: Dirk Behme <dirk.be...@googlemail.com>
New tap_get_tms_path() by
Holger Schurig <hs4...@mail.mn-solutions.de>
---
src/jtag/ft2232.c | 60 ++++++++++-------
src/jtag/ftdi.h | 1
src/jtag/jtag.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/jtag/jtag.h | 9 +-
src/xsvf/xsvf.c | 10 ++
5 files changed, 224 insertions(+), 38 deletions(-)
Index: trunk/src/jtag/jtag.c
===================================================================
--- trunk.orig/src/jtag/jtag.c
+++ trunk/src/jtag/jtag.c
@@ -1645,6 +1645,7 @@ int jtag_validate_chain(void)
}
total_ir_length += 2;
+ LOG_OUTPUT("Total ir length: %d\n", total_ir_length);
ir_test = malloc(CEIL(total_ir_length, 8));
buf_set_ones(ir_test, total_ir_length);
@@ -1682,6 +1683,7 @@ int jtag_validate_chain(void)
chain_pos += tap->ir_length;
}
+ LOG_OUTPUT("Chain pos: %d, ir_test: 0x%08x\n", chain_pos,
buf_get_u32(ir_test, 0, 32));
val = buf_get_u32(ir_test, chain_pos, 2);
if (val != 0x3)
{
@@ -2964,8 +2966,7 @@ tap_state_t tap_get_end_state()
{
return end_state_follower;
}
-
-
+#if 0
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() */
@@ -2996,7 +2997,6 @@ int tap_move_ndx( tap_state_t astate )
return ndx;
}
-
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
@@ -3037,6 +3037,178 @@ int tap_get_tms_path( tap_state_t from,
/* @todo: support other than 7 clocks ? */
return tms_seqs[tap_move_ndx(from)][tap_move_ndx(to)];
}
+#endif
+
+#define _DEBUG_JTAG_IO_
+#define OMAP3_HACK
+
+void tap_get_tms_path( tap_state_t from, tap_state_t to, tap_move_t *tap_move)
+{
+ LOG_OUTPUT("jtag move from %s to %s\n", tap_state_name(from),
tap_state_name(to));
+
+ /* you can reach from every state to any other state in 7 or less
shifts */
+ u8 bit[7];
+ u8 i, clocks = 0;
+ u8 tms = 0;
+#ifdef _DEBUG_JTAG_IO_
+ tap_state_t cur_state = from;
+#endif
+
+ for (i = 0; i < 2; i++) {
+ if (from == TAP_RESET) {
+ if (to == TAP_RESET) {
+ bit[clocks++] = 1;
+#ifdef OMAP3_HACK /* FIXME: Why is this needed to for correct ID code
detection?? */
+ bit[clocks++] = 1;
+ bit[clocks++] = 1;
+ bit[clocks++] = 1;
+ bit[clocks++] = 1;
+ bit[clocks++] = 1;
+#endif
+ } else {
+ bit[clocks++] = 0;
+ from = TAP_IDLE;
+ }}
+ if (from == to) break;
+
+ if (from == TAP_IDLE) {
+ bit[clocks++] = 1;
+ from = TAP_DRSELECT;
+ }
+ if (from == to) break;
+
+ if (from == TAP_DRSELECT && ((to >= TAP_IRSELECT) || (to ==
TAP_RESET))) {
+ bit[clocks++] = 1;
+ from = TAP_IRSELECT;
+ } else
+ if (from == TAP_DRSELECT) {
+ bit[clocks++] = 0;
+ from = TAP_DRCAPTURE;
+ }
+ if (from == to) break;
+
+ if (from == TAP_IRSELECT && (to == TAP_RESET)) {
+ bit[clocks++] = 1;
+ from = TAP_RESET;
+ } else
+ if (from == TAP_IRSELECT) {
+ bit[clocks++] = 0;
+ from = TAP_IRCAPTURE;
+ }
+ if (from == to) break;
+
+ if (from == TAP_DRCAPTURE && to == TAP_DRSHIFT) {
+ bit[clocks++] = 0;
+ from = TAP_DRSHIFT;
+ } else
+ if (from == TAP_DRCAPTURE) {
+ bit[clocks++] = 1;
+ from = TAP_DREXIT1;
+ } else
+ if (from == TAP_IRCAPTURE && to == TAP_IRSHIFT) {
+ bit[clocks++] = 0;
+ from = TAP_IRSHIFT;
+ } else
+ if (from == TAP_IRCAPTURE) {
+ bit[clocks++] = 1;
+ from = TAP_IREXIT1;
+ }
+ if (from == to) break;
+
+ if (from == TAP_DRSHIFT) {
+ bit[clocks++] = 1;
+ from = TAP_DREXIT1;
+ } else
+ if (from == TAP_IRSHIFT) {
+ bit[clocks++] = 1;
+ from = TAP_IREXIT1;
+ }
+ if (from == to) break;
+
+ if (from == TAP_DREXIT1 && (to == TAP_DRPAUSE || to ==
TAP_DREXIT2)) {
+ bit[clocks++] = 0;
+ from = TAP_DRPAUSE;
+ } else
+ if (from == TAP_DREXIT1) {
+ bit[clocks++] = 1;
+ from = TAP_DRUPDATE;
+ } else
+ if (from == TAP_IREXIT1 && (to == TAP_IRPAUSE || to ==
TAP_IREXIT2)) {
+ bit[clocks++] = 0;
+ from = TAP_IRPAUSE;
+ } else
+ if (from == TAP_IREXIT1) {
+ bit[clocks++] = 1;
+ from = TAP_IRUPDATE;
+ }
+ if (from == to) break;
+
+ if (from == TAP_DRPAUSE) {
+ bit[clocks++] = 1;
+ from = TAP_DREXIT2;
+ } else
+ if (from == TAP_IRPAUSE) {
+ bit[clocks++] = 1;
+ from = TAP_IREXIT2;
+ }
+ if (from == to) break;
+
+ if (from == TAP_DREXIT2 && to >= TAP_DRSHIFT && to <=
TAP_DRPAUSE) {
+ bit[clocks++] = 0;
+ from = TAP_DRSHIFT;
+ } else
+ if (from == TAP_DREXIT2) {
+ bit[clocks++] = 1;
+ from = TAP_DRUPDATE;
+ } else
+ if (from == TAP_IREXIT2 && to >= TAP_IRSHIFT && to <=
TAP_IRPAUSE) {
+ bit[clocks++] = 0;
+ from = TAP_IRSHIFT;
+ } else
+ if (from == TAP_IREXIT2) {
+ bit[clocks++] = 1;
+ from = TAP_IRUPDATE;
+ }
+ if (from == to) break;
+
+ if (from == TAP_DRUPDATE || from == TAP_IRUPDATE) {
+ if (to == TAP_IDLE) {
+ bit[clocks++] = 0;
+ from = TAP_IDLE;
+ } else {
+ bit[clocks++] = 1;
+ from = TAP_DRSELECT;
+ }
+ }
+ if (from == to) break;
+
+ if (from == TAP_IDLE) {
+ bit[clocks++] = 1;
+ from = TAP_DRSELECT;
+ }
+ if (from == to) break;
+
+ if (clocks > sizeof(bit)) {
+ LOG_ERROR("not enough clocks");
+ break;
+ }
+ }
+
+ for (i = 0; i < clocks; i++) {
+ tms |= (bit[i] << i);
+ }
+
+ tap_move->tms = tms;
+ tap_move->clocks = clocks;
+
+#ifdef _DEBUG_JTAG_IO_
+ for (i = 0; i < clocks; i++) {
+ bool t = tms & (1 << i);
+ cur_state = tap_state_transition(cur_state, t);
+ LOG_OUTPUT(" tms %d, advance to %s %d\n", t,
tap_state_name(cur_state), cur_state);
+ }
+#endif
+}
bool tap_is_state_stable(tap_state_t astate)
Index: trunk/src/jtag/ft2232.c
===================================================================
--- trunk.orig/src/jtag/ft2232.c
+++ trunk/src/jtag/ft2232.c
@@ -587,6 +587,7 @@ void ft2232_add_pathmove(pathmove_comman
void ft2232_add_scan(int ir_scan, enum scan_type type, u8* buffer, int
scan_size)
{
+ tap_move_t tap_move;
int num_bytes = (scan_size + 7) / 8;
int bits_left = scan_size;
int cur_byte = 0;
@@ -598,17 +599,19 @@ void ft2232_add_scan(int ir_scan, enum s
/* command "Clock Data to TMS/CS Pin (no Read)" */
BUFFER_ADD = 0x4b;
- BUFFER_ADD = 0x6; /* scan 7 bits */
-
- /* TMS data bits */
+ /* TMS data bits and clock count */
if (ir_scan)
{
- BUFFER_ADD = tap_get_tms_path(tap_get_state(),
TAP_IRSHIFT);
+ tap_get_tms_path(tap_get_state(), TAP_IRSHIFT,
&tap_move);
+ BUFFER_ADD = tap_move.clocks - 1;
+ BUFFER_ADD = tap_move.tms;
tap_set_state(TAP_IRSHIFT);
}
else
{
- BUFFER_ADD = tap_get_tms_path(tap_get_state(),
TAP_DRSHIFT);
+ tap_get_tms_path(tap_get_state(), TAP_DRSHIFT,
&tap_move);
+ BUFFER_ADD = tap_move.clocks - 1;
+ BUFFER_ADD = tap_move.tms;
tap_set_state(TAP_DRSHIFT);
}
/* LOG_DEBUG("added TMS scan (no read)"); */
@@ -729,9 +732,10 @@ void ft2232_add_scan(int ir_scan, enum s
BUFFER_ADD = 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_get_tms_path( tap_get_state(), tap_get_end_state(),
&tap_move);
+ BUFFER_ADD = tap_move.clocks - 1;
+ BUFFER_ADD = tap_move.tms | (last_bit << 7);
tap_set_state( tap_get_end_state() );
}
}
@@ -739,6 +743,7 @@ void ft2232_add_scan(int ir_scan, enum s
int ft2232_large_scan(scan_command_t* cmd, enum scan_type type, u8* buffer,
int scan_size)
{
+ tap_move_t tap_move;
int num_bytes = (scan_size + 7) / 8;
int bits_left = scan_size;
int cur_byte = 0;
@@ -761,10 +766,10 @@ int ft2232_large_scan(scan_command_t* cm
/* 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);
+ /* TMS data bits and clock */
+ tap_get_tms_path( tap_get_state(), TAP_DRSHIFT, &tap_move);
+ BUFFER_ADD = tap_move.clocks - 1;
+ BUFFER_ADD = tap_move.tms;
tap_set_state(TAP_DRSHIFT);
}
@@ -916,9 +921,10 @@ int ft2232_large_scan(scan_command_t* cm
BUFFER_ADD = 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() );
+ tap_get_tms_path( tap_get_state(), tap_get_end_state(),
&tap_move);
+ BUFFER_ADD = tap_move.clocks - 1;
+ BUFFER_ADD = tap_move.tms | (last_bit << 7);
+ tap_set_state(tap_get_end_state());
}
if (type != SCAN_OUT)
@@ -1256,6 +1262,7 @@ void stm32stick_reset(int trst, int srst
int ft2232_execute_queue()
{
jtag_command_t* cmd = jtag_command_queue; /* currently processed
command */
+ tap_move_t tap_move;
u8* buffer;
int scan_size; /* size of IR or DR scan */
enum scan_type type;
@@ -1331,10 +1338,12 @@ int ft2232_execute_queue()
{
/* 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);
+ /* TMS data bits and clock */
+ tap_get_tms_path( tap_get_state(), TAP_IDLE,
&tap_move);
+ BUFFER_ADD = tap_move.clocks - 1;
+ BUFFER_ADD = tap_move.tms;
+
tap_set_state(TAP_IDLE);
require_send = 1;
}
@@ -1361,10 +1370,10 @@ int ft2232_execute_queue()
{
/* 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() );
+ /* TMS data bits and clock */
+ tap_get_tms_path( tap_get_state(),
tap_get_end_state(), &tap_move);
+ BUFFER_ADD = tap_move.clocks - 1;
+ BUFFER_ADD = tap_move.tms;
tap_set_state( tap_get_end_state() );
/* LOG_DEBUG("added TMS scan (no read)"); */
}
@@ -1390,11 +1399,10 @@ int ft2232_execute_queue()
/* 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_get_end_state() );
- /* LOG_DEBUG("added TMS scan (no read)"); */
+ /* TMS data bits and clock */
+ tap_get_tms_path( tap_get_state(), tap_get_end_state(),
&tap_move);
+ BUFFER_ADD = tap_move.clocks - 1;
+ BUFFER_ADD = tap_move.tms;
tap_set_state( tap_get_end_state() );
require_send = 1;
#ifdef _DEBUG_JTAG_IO_
Index: trunk/src/jtag/jtag.h
===================================================================
--- trunk.orig/src/jtag/jtag.h
+++ trunk/src/jtag/jtag.h
@@ -57,8 +57,11 @@ typedef struct tap_transition_s
tap_state_t low;
} tap_transition_t;
-//extern tap_transition_t tap_transitions[16]; /* describe the TAP state
diagram */
-
+typedef struct tap_move_s
+{
+ u8 tms;
+ u8 clocks;
+} tap_move_t;
/*-----<Cable Helper API>-------------------------------------------*/
@@ -131,7 +134,7 @@ tap_state_t tap_get_end_state(void);
* @param to is the resultant or final state
* @return int - a 7 bit sequence, with the first bit in the sequence at bit 0.
*/
-int tap_get_tms_path(tap_state_t from, tap_state_t to);
+void tap_get_tms_path(tap_state_t, tap_state_t, tap_move_t *);
/**
* Function tap_move_ndx
Index: trunk/src/jtag/ftdi.h
===================================================================
--- trunk.orig/src/jtag/ftdi.h
+++ trunk/src/jtag/ftdi.h
@@ -252,7 +252,6 @@ extern "C" {
#endif
int ftdi_init(struct ftdi_context *ftdi);
- struct ftdi_context *ftdi_new();
int ftdi_set_interface(struct ftdi_context *ftdi, enum ftdi_interface
interface);
void ftdi_deinit(struct ftdi_context *ftdi);
Index: trunk/src/xsvf/xsvf.c
===================================================================
--- trunk.orig/src/xsvf/xsvf.c
+++ trunk/src/xsvf/xsvf.c
@@ -183,9 +183,13 @@ static void xsvf_add_statemove(tap_state
{
tap_state_t moves[7]; /* max # of transitions */
tap_state_t curstate = cmd_queue_cur_state;
+ tap_move_t tap_move;
int i;
+ u8 move, clocks;
- u8 move = tap_get_tms_path(cmd_queue_cur_state, state);
+ tap_get_tms_path(cmd_queue_cur_state, state, &tap_move);
+ clocks = tap_move.clocks;
+ move = tap_move.tms;
if (state != TAP_RESET && state==cmd_queue_cur_state)
return;
@@ -196,7 +200,7 @@ static void xsvf_add_statemove(tap_state
return;
}
- for (i=0; i<7; i++)
+ for (i=0; i<clocks; i++)
{
int j = (move >> i) & 1;
if (j)
@@ -210,7 +214,7 @@ static void xsvf_add_statemove(tap_state
moves[i] = curstate;
}
- jtag_add_pathmove(7, moves);
+ jtag_add_pathmove(clocks, moves);
}
int xsvf_register_commands(struct command_context_s *cmd_ctx)
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development