Patch by Michael Schwingen that
[fw/openocd] / src / jtag / bitbang.c
index 61248364952e2fcb9643f1aa63e3a2b845ae2dc1..19afdbf0b8454397547c71949fde276c144b109e 100644 (file)
@@ -132,21 +132,35 @@ void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
        enum tap_state saved_end_state = end_state;
        int bit_cnt;
        
-       if (ir_scan)
-               bitbang_end_state(TAP_SI);
-       else
-               bitbang_end_state(TAP_SD);
+       if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI))))
+       {
+               if (ir_scan)
+                       bitbang_end_state(TAP_SI);
+               else
+                       bitbang_end_state(TAP_SD);
 
-       bitbang_state_move();
-       bitbang_end_state(saved_end_state);
+               bitbang_state_move();
+               bitbang_end_state(saved_end_state);
+       }
 
        for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++)
        {
+               /* set TMS high on the last bit unless we want to end in TAP_SD/SI */
+               int tms;
+               if ((ir_scan && (end_state == TAP_SI)) ||
+                       (!ir_scan && (end_state == TAP_SD)))
+               {
+                       tms = 0;
+               } else {
+                       tms = (bit_cnt==scan_size-1) ? 1 : 0;
+               }
+               
                /* if we're just reading the scan, but don't care about the output
                 * default to outputting 'low', this also makes valgrind traces more readable,
                 * as it removes the dependency on an uninitialised value
                 */ 
-               if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1)) {
+               if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1))
+               {
                        bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 1);
                        bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 1);
                } else {
@@ -182,13 +196,22 @@ int bitbang_execute_queue(void)
        int scan_size;
        enum scan_type type;
        u8 *buffer;
+       int retval;
        
        if (!bitbang_interface)
        {
                ERROR("BUG: Bitbang interface called, but not yet initialized");
                exit(-1);
        }
+       
+       /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
+        * that wasn't handled by a caller-provided error handler
+        */ 
+       retval = ERROR_OK;
                
+       if(bitbang_interface->blink)
+               bitbang_interface->blink(1);
+
        while (cmd)
        {
                switch (cmd->type)
@@ -234,7 +257,7 @@ int bitbang_execute_queue(void)
                                break;
                        case JTAG_SCAN:
 #ifdef _DEBUG_JTAG_IO_
-                               DEBUG("scan end in %i", cmd->cmd.scan->end_state);
+                               DEBUG("%s scan end in %i",  (cmd->cmd.scan->ir_scan) ? "IR" : "DR", cmd->cmd.scan->end_state);
 #endif
                                if (cmd->cmd.scan->end_state != -1)
                                        bitbang_end_state(cmd->cmd.scan->end_state);
@@ -242,7 +265,7 @@ int bitbang_execute_queue(void)
                                type = jtag_scan_type(cmd->cmd.scan);
                                bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
                                if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
-                                       return ERROR_JTAG_QUEUE_FAILED;
+                                       retval = ERROR_JTAG_QUEUE_FAILED;
                                if (buffer)
                                        free(buffer);
                                break;
@@ -258,7 +281,9 @@ int bitbang_execute_queue(void)
                }
                cmd = cmd->next;
        }
+       if(bitbang_interface->blink)
+               bitbang_interface->blink(0);
        
-       return ERROR_OK;
+       return retval;
 }