diff options
Diffstat (limited to 'fpga/xilinx/programmer/dependencies/libxsvf/tap.c')
-rw-r--r-- | fpga/xilinx/programmer/dependencies/libxsvf/tap.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/fpga/xilinx/programmer/dependencies/libxsvf/tap.c b/fpga/xilinx/programmer/dependencies/libxsvf/tap.c new file mode 100644 index 0000000..c258fde --- /dev/null +++ b/fpga/xilinx/programmer/dependencies/libxsvf/tap.c @@ -0,0 +1,173 @@ +/* + * Lib(X)SVF - A library for implementing SVF and XSVF JTAG players + * + * Copyright (C) 2009 RIEGL Research ForschungsGmbH + * Copyright (C) 2009 Clifford Wolf <clifford@clifford.at> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "libxsvf.h" + +static void tap_transition(struct libxsvf_host *h, int v) +{ + LIBXSVF_HOST_PULSE_TCK(v, -1, -1, 0, 0); +} + +int libxsvf_tap_walk(struct libxsvf_host *h, enum libxsvf_tap_state s) +{ + int i, j; + for (i=0; s != h->tap_state; i++) + { + switch (h->tap_state) + { + /* Special States */ + case LIBXSVF_TAP_INIT: + for (j = 0; j < 6; j++) + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_RESET; + break; + case LIBXSVF_TAP_RESET: + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_IDLE; + break; + case LIBXSVF_TAP_IDLE: + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_DRSELECT; + break; + + /* DR States */ + case LIBXSVF_TAP_DRSELECT: + if (s >= LIBXSVF_TAP_IRSELECT || s == LIBXSVF_TAP_RESET) { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_IRSELECT; + } else { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_DRCAPTURE; + } + break; + case LIBXSVF_TAP_DRCAPTURE: + if (s == LIBXSVF_TAP_DRSHIFT) { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_DRSHIFT; + } else { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_DREXIT1; + } + break; + case LIBXSVF_TAP_DRSHIFT: + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_DREXIT1; + break; + case LIBXSVF_TAP_DREXIT1: + if (s == LIBXSVF_TAP_DRPAUSE) { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_DRPAUSE; + } else { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_DRUPDATE; + } + break; + case LIBXSVF_TAP_DRPAUSE: + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_DREXIT2; + break; + case LIBXSVF_TAP_DREXIT2: + if (s == LIBXSVF_TAP_DRSHIFT) { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_DRSHIFT; + } else { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_DRUPDATE; + } + break; + case LIBXSVF_TAP_DRUPDATE: + if (s == LIBXSVF_TAP_IDLE) { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_IDLE; + } else { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_DRSELECT; + } + break; + + /* IR States */ + case LIBXSVF_TAP_IRSELECT: + if (s == LIBXSVF_TAP_RESET) { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_RESET; + } else { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_IRCAPTURE; + } + break; + case LIBXSVF_TAP_IRCAPTURE: + if (s == LIBXSVF_TAP_IRSHIFT) { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_IRSHIFT; + } else { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_IREXIT1; + } + break; + case LIBXSVF_TAP_IRSHIFT: + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_IREXIT1; + break; + case LIBXSVF_TAP_IREXIT1: + if (s == LIBXSVF_TAP_IRPAUSE) { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_IRPAUSE; + } else { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_IRUPDATE; + } + break; + case LIBXSVF_TAP_IRPAUSE: + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_IREXIT2; + break; + case LIBXSVF_TAP_IREXIT2: + if (s == LIBXSVF_TAP_IRSHIFT) { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_IRSHIFT; + } else { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_IRUPDATE; + } + break; + case LIBXSVF_TAP_IRUPDATE: + if (s == LIBXSVF_TAP_IDLE) { + tap_transition(h, 0); + h->tap_state = LIBXSVF_TAP_IDLE; + } else { + tap_transition(h, 1); + h->tap_state = LIBXSVF_TAP_DRSELECT; + } + break; + + default: + LIBXSVF_HOST_REPORT_ERROR("Illegal tap state."); + return -1; + } + if (h->report_tapstate) + LIBXSVF_HOST_REPORT_TAPSTATE(); + if (i>10) { + LIBXSVF_HOST_REPORT_ERROR("Loop in tap walker."); + return -1; + } + } + + return 0; +} |