You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
4.4 KiB
174 lines
4.4 KiB
/*
|
|
* 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;
|
|
}
|