Merge branch 'master' of ssh://dbrownell@openocd.git.sourceforge.net/gitroot/openocd...
[openocd.git] / src / jtag / ft2232.c
index 1a49df9cba0210f34f0e25cc6456840bc6126624..87f02d60bcd5e5d841bd088bce0dd5ae8a979656 100644 (file)
@@ -1,13 +1,16 @@
 /***************************************************************************
+*   Copyright (C) 2009 by Øyvind Harboe                                   *
+*      Øyvind Harboe <oyvind.harboe@zylin.com>                               *
+*                                                                         *
+*   Copyright (C) 2009 by SoftPLC Corporation.  http://softplc.com        *
+*      Dick Hollenbeck <dick@softplc.com>                                    *
+*                                                                         *
 *   Copyright (C) 2004, 2006 by Dominic Rath                              *
 *   Dominic.Rath@gmx.de                                                   *
 *                                                                         *
 *   Copyright (C) 2008 by Spencer Oliver                                  *
 *   spen@spen-soft.co.uk                                                  *
 *                                                                         *
-*   Copyright (C) 2009 by SoftPLC Corporation.  http://softplc.com        *
-*      Dick Hollenbeck <dick@softplc.com>                                    *
-*                                                                         *
 *   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     *
@@ -766,33 +769,48 @@ static int ft2232_send_and_recv(jtag_command_t* first, jtag_command_t* last)
  */
 static void ft2232_add_pathmove(tap_state_t* path, int num_states)
 {
-       int                     tms_bits = 0;
-       int                     state_ndx;
-       tap_state_t     walker = tap_get_state();
+       int state_count = 0;
 
        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)
+       while (num_states)
        {
-               tap_state_t     desired_next_state = path[state_ndx];
+               unsigned char   tms_byte = 0;       /* zero this on each MPSSE batch */
+               int             bit_count = 0;
+               int             num_states_batch = num_states > 7 ? 7 : num_states;
 
-               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
-               {
-                       LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
-                                       tap_state_name(walker), tap_state_name(desired_next_state));
-                       exit(-1);
-               }
+               /* command "Clock Data to TMS/CS Pin (no Read)" */
+               buffer_write(0x4b);
 
-               walker = desired_next_state;
-       }
+               /* number of states remaining */
+               buffer_write(num_states_batch - 1);
+
+               while (num_states_batch--) {
+                       /* either TMS=0 or TMS=1 must work ... */
+                       if (tap_state_transition(tap_get_state(), false)
+                                               == path[state_count])
+                               buf_set_u32(&tms_byte, bit_count++, 1, 0x0);
+                       else if (tap_state_transition(tap_get_state(), true)
+                                               == path[state_count])
+                               buf_set_u32(&tms_byte, bit_count++, 1, 0x1);
+
+                       /* ... or else the caller goofed BADLY */
+                       else {
+                               LOG_ERROR("BUG: %s -> %s isn't a valid "
+                                               "TAP state transition",
+                                       tap_state_name(tap_get_state()),
+                                       tap_state_name(path[state_count]));
+                               exit(-1);
+                       }
 
-       clock_tms(0x4b,  tms_bits, num_states, 0);
+                       tap_set_state(path[state_count]);
+                       state_count++;
+                       num_states--;
+               }
 
+               buffer_write(tms_byte);
+       }
        tap_set_end_state(tap_get_state());
 }
 
@@ -1572,8 +1590,16 @@ static int ft2232_execute_statemove(jtag_command_t *cmd)
        }
        ft2232_end_state(cmd->cmd.statemove->end_state);
 
-       /* move to end state */
-       if (tap_get_state() != tap_get_end_state())
+       /* For TAP_RESET, ignore the current recorded state.  It's often
+        * wrong at server startup, and this transation is critical whenever
+        * it's requested.
+        */
+       if (tap_get_end_state() == TAP_RESET) {
+               clock_tms(0x4b,  0xff, 5, 0);
+               require_send = 1;
+
+       /* shortest-path move to desired end state */
+       } else if (tap_get_state() != tap_get_end_state())
        {
                move_to_state(tap_get_end_state());
                require_send = 1;
@@ -1686,6 +1712,11 @@ static int ft2232_execute_reset(jtag_command_t *cmd)
                first_unsent = cmd;
        }
 
+       if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
+       {
+               tap_set_state(TAP_RESET);
+       }
+
        layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
        require_send = 1;
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)