Improve encapsulation of JTAG event handling:
[fw/openocd] / src / jtag / bitbang.c
index fe5f86c41db8dc79cc90ba21a835da03e1fc077b..f5bfd15e311cadcde25181a97ed3d5d814e9a9b7 100644 (file)
 #endif
 
 #include "bitbang.h"
-
-/* project specific includes */
-#include "log.h"
-#include "types.h"
-#include "jtag.h"
-#include "configuration.h"
-
-/* system includes */
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
+#include "interface.h"
+#include "commands.h"
 
 /**
  * Function bitbang_stableclocks
@@ -84,12 +74,13 @@ static void bitbang_end_state(tap_state_t state)
        }
 }
 
-static void bitbang_state_move(void)
+static void bitbang_state_move(int skip)
 {
        int i=0, tms=0;
        u8 tms_scan = 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());
 
-       for (i = 0; i < 7; i++)
+       for (i = skip; i < tms_count; i++)
        {
                tms = (tms_scan >> i) & 1;
                bitbang_interface->write(0, tms, 0);
@@ -146,7 +137,7 @@ static void bitbang_runtest(int num_cycles)
        if (tap_get_state() != TAP_IDLE)
        {
                bitbang_end_state(TAP_IDLE);
-               bitbang_state_move();
+               bitbang_state_move(0);
        }
 
        /* execute num_cycles */
@@ -160,7 +151,7 @@ static void bitbang_runtest(int num_cycles)
        /* finish in end_state */
        bitbang_end_state(saved_end_state);
        if (tap_get_state() != tap_get_end_state())
-               bitbang_state_move();
+               bitbang_state_move(0);
 }
 
 
@@ -179,7 +170,7 @@ static void bitbang_stableclocks(int num_cycles)
 
 
 
-static void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
+static void bitbang_scan(bool ir_scan, enum scan_type type, u8 *buffer, int scan_size)
 {
        tap_state_t saved_end_state = tap_get_end_state();
        int bit_cnt;
@@ -191,7 +182,7 @@ static void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_
                else
                        bitbang_end_state(TAP_DRSHIFT);
 
-               bitbang_state_move();
+               bitbang_state_move(0);
                bitbang_end_state(saved_end_state);
        }
 
@@ -227,22 +218,14 @@ static void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_
                }
        }
 
-       /* TAP_DRSHIFT & TAP_IRSHIFT are illegal end states, so we always transition to the pause
-        * state which is a legal stable state from which statemove will work.
-        *
-        * Exit1 -> Pause
-        */
-       bitbang_interface->write(0, 0, 0);
-       bitbang_interface->write(1, 0, 0);
-       bitbang_interface->write(CLOCK_IDLE(), 0, 0);
-
-       if (ir_scan)
-               tap_set_state(TAP_IRPAUSE);
-       else
-               tap_set_state(TAP_DRPAUSE);
-
        if (tap_get_state() != tap_get_end_state())
-               bitbang_state_move();
+       {
+               /* we *KNOW* the above loop transitioned out of
+                * the shift state, so we skip the first state
+                * and move directly to the end state.
+                */
+               bitbang_state_move(1);
+       }
 }
 
 int bitbang_execute_queue(void)
@@ -271,18 +254,11 @@ int bitbang_execute_queue(void)
        {
                switch (cmd->type)
                {
-                       case JTAG_END_STATE:
-#ifdef _DEBUG_JTAG_IO_
-                               LOG_DEBUG("end_state: %s", tap_state_name(cmd->cmd.end_state->end_state) );
-#endif
-                               if (cmd->cmd.end_state->end_state != TAP_INVALID)
-                                       bitbang_end_state(cmd->cmd.end_state->end_state);
-                               break;
                        case JTAG_RESET:
 #ifdef _DEBUG_JTAG_IO_
                                LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
 #endif
-                               if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST)))
+                               if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
                                {
                                        tap_set_state(TAP_RESET);
                                }
@@ -292,8 +268,7 @@ int bitbang_execute_queue(void)
 #ifdef _DEBUG_JTAG_IO_
                                LOG_DEBUG("runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles, tap_state_name(cmd->cmd.runtest->end_state) );
 #endif
-                               if (cmd->cmd.runtest->end_state != TAP_INVALID)
-                                       bitbang_end_state(cmd->cmd.runtest->end_state);
+                               bitbang_end_state(cmd->cmd.runtest->end_state);
                                bitbang_runtest(cmd->cmd.runtest->num_cycles);
                                break;
 
@@ -308,9 +283,8 @@ int bitbang_execute_queue(void)
 #ifdef _DEBUG_JTAG_IO_
                                LOG_DEBUG("statemove end in %s", tap_state_name(cmd->cmd.statemove->end_state));
 #endif
-                               if (cmd->cmd.statemove->end_state != TAP_INVALID)
-                                       bitbang_end_state(cmd->cmd.statemove->end_state);
-                               bitbang_state_move();
+                               bitbang_end_state(cmd->cmd.statemove->end_state);
+                               bitbang_state_move(0);
                                break;
                        case JTAG_PATHMOVE:
 #ifdef _DEBUG_JTAG_IO_
@@ -323,8 +297,7 @@ int bitbang_execute_queue(void)
 #ifdef _DEBUG_JTAG_IO_
                                LOG_DEBUG("%s scan end in %s",  (cmd->cmd.scan->ir_scan) ? "IR" : "DR", tap_state_name(cmd->cmd.scan->end_state) );
 #endif
-                               if (cmd->cmd.scan->end_state != TAP_INVALID)
-                                       bitbang_end_state(cmd->cmd.scan->end_state);
+                               bitbang_end_state(cmd->cmd.scan->end_state);
                                scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
                                type = jtag_scan_type(cmd->cmd.scan);
                                bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);