jtag: jtag_add_ir_scan() now takes a single field
[fw/openocd] / src / jtag / drivers / driver.c
index cadd88e8f400fc634cd3dbf24704be1c5306ddea..57bc28d1601673956339ece10d2b69e0942bce4f 100644 (file)
@@ -2,7 +2,7 @@
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
- *   Copyright (C) 2007,2008 Øyvind Harboe                                 *
+ *   Copyright (C) 2007-2009 Øyvind Harboe                                 *
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
  *   Copyright (C) 2009 SoftPLC Corporation                                *
 #include "config.h"
 #endif
 
-#include "interface.h"
-#include "minidriver.h"
-#include "command.h"
+#include <jtag/jtag.h>
+#include <jtag/interface.h>
+#include <jtag/commands.h>
+#include <jtag/minidriver.h>
+#include <helper/command.h>
 
 struct jtag_callback_entry
 {
@@ -62,7 +64,6 @@ static void jtag_callback_queue_reset(void)
  */
 static void cmd_queue_scan_field_clone(struct scan_field * dst, const struct scan_field * src)
 {
-       dst->tap                = src->tap;
        dst->num_bits   = src->num_bits;
        dst->out_value  = buf_cpy(src->out_value, cmd_queue_alloc(DIV_ROUND_UP(src->num_bits, 8)), src->num_bits);
        dst->in_value   = src->in_value;
@@ -73,7 +74,7 @@ static void cmd_queue_scan_field_clone(struct scan_field * dst, const struct sca
  * see jtag_add_ir_scan()
  *
  */
-int interface_jtag_add_ir_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
+int interface_jtag_add_ir_scan(struct jtag_tap* active, const struct scan_field *in_fields, tap_state_t state)
 {
        size_t num_taps = jtag_tap_count_enabled();
 
@@ -100,33 +101,18 @@ int interface_jtag_add_ir_scan(int in_num_fields, const struct scan_field *in_fi
        {
                /* search the input field list for fields for the current TAP */
 
-               bool found = false;
-
-               for (int j = 0; j < in_num_fields; j++)
+               if (tap == active)
                {
-                       if (tap != in_fields[j].tap)
-                               continue;
-
                        /* if TAP is listed in input fields, copy the value */
-
-                       found = true;
-
                        tap->bypass = 0;
 
-                       assert(in_fields[j].num_bits == tap->ir_length); /* input fields must have the same length as the TAP's IR */
-
-                       cmd_queue_scan_field_clone(field, in_fields + j);
-
-                       break;
-               }
-
-               if (!found)
+                       cmd_queue_scan_field_clone(field, in_fields);
+               } else
                {
                        /* if a TAP isn't listed in input fields, set it to BYPASS */
 
                        tap->bypass = 1;
 
-                       field->tap                      = tap;
                        field->num_bits         = tap->ir_length;
                        field->out_value        = buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8)), tap->ir_length);
                        field->in_value         = NULL; /* do not collect input for tap's in bypass */
@@ -176,7 +162,7 @@ int interface_jtag_add_plain_ir_scan(int in_num_fields, const struct scan_field
  * see jtag_add_dr_scan()
  *
  */
-int interface_jtag_add_dr_scan(int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
+int interface_jtag_add_dr_scan(struct jtag_tap* active, int in_num_fields, const struct scan_field *in_fields, tap_state_t state)
 {
        /* count devices in bypass */
 
@@ -213,13 +199,14 @@ int interface_jtag_add_dr_scan(int in_num_fields, const struct scan_field *in_fi
 
                if (!tap->bypass)
                {
-                       struct scan_field * start_field = field;        /* keep initial position for assert() */
+                       assert(active == tap);
+#ifndef NDEBUG
+                       /* remember initial position for assert() */
+                       struct scan_field *start_field = field;
+#endif /* NDEBUG */
 
                        for (int j = 0; j < in_num_fields; j++)
                        {
-                               if (tap != in_fields[j].tap)
-                                       continue;
-
                                cmd_queue_scan_field_clone(field, in_fields + j);
 
                                field++;
@@ -231,7 +218,6 @@ int interface_jtag_add_dr_scan(int in_num_fields, const struct scan_field *in_fi
                /* if a TAP is bypassed, generated a dummy bit*/
                else
                {
-                       field->tap                      = tap;
                        field->num_bits         = 1;
                        field->out_value        = NULL;
                        field->in_value         = NULL;
@@ -315,7 +301,6 @@ void interface_jtag_add_dr_out(struct jtag_tap *target_tap,
                                size_t scan_size = num_bits[j];
                                buf_set_u32(out_value, 0, scan_size, value[j]);
 
-                               field->tap                      = tap;
                                field->num_bits         = scan_size;
                                field->out_value        = buf_cpy(out_value, cmd_queue_alloc(DIV_ROUND_UP(scan_size, 8)), scan_size);
                                field->in_value         = NULL;
@@ -328,7 +313,6 @@ void interface_jtag_add_dr_out(struct jtag_tap *target_tap,
                else
                {
 
-                       field->tap                              = tap;
                        field->num_bits                 = 1;
                        field->out_value                = NULL;
                        field->in_value                 = NULL;
@@ -383,6 +367,31 @@ int interface_jtag_add_tlr(void)
        return ERROR_OK;
 }
 
+int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state)
+{
+       struct jtag_command *cmd;
+
+       cmd = cmd_queue_alloc(sizeof(struct jtag_command));
+       if (cmd == NULL)
+               return ERROR_FAIL;
+
+       cmd->type = JTAG_TMS;
+       cmd->cmd.tms = cmd_queue_alloc(sizeof(*cmd->cmd.tms));
+       if (!cmd->cmd.tms)
+               return ERROR_FAIL;
+
+       /* copy the bits; our caller doesn't guarantee they'll persist */
+       cmd->cmd.tms->num_bits = num_bits;
+       cmd->cmd.tms->bits = buf_cpy(seq,
+                       cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);
+       if (!cmd->cmd.tms->bits)
+               return ERROR_FAIL;
+
+       jtag_queue_command(cmd);
+
+       return ERROR_OK;
+}
+
 int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
 {
        /* allocate memory for a new list member */
@@ -525,3 +534,30 @@ void interface_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t
        jtag_add_callback4(jtag_convert_to_callback4, data0, (jtag_callback_data_t)callback, 0, 0);
 }
 
+
+/* A minidriver can use use an inline versions of this API level fn */
+void jtag_add_dr_out(struct jtag_tap* tap,
+               int num_fields, const int* num_bits, const uint32_t* value,
+               tap_state_t end_state)
+{
+       assert(end_state != TAP_RESET);
+       assert(end_state != TAP_INVALID);
+
+       cmd_queue_cur_state = end_state;
+
+       interface_jtag_add_dr_out(tap,
+                       num_fields, num_bits, value,
+                       end_state);
+}
+
+void jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0)
+{
+       interface_jtag_add_callback(f, data0);
+}
+
+void jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,
+               jtag_callback_data_t data1, jtag_callback_data_t data2,
+               jtag_callback_data_t data3)
+{
+       interface_jtag_add_callback4(f, data0, data1, data2, data3);
+}