[ 1074347 ] SVF Player (4 patches: jtag-svf, -inc1, -goto_state, -vec-hexa)

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@691 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Kolja Waschk 17 years ago
parent f5ddf85b38
commit 7d7c3d6e40

@ -28,7 +28,8 @@ SUBDIRS = \
tap \
part \
bus \
cmd
cmd \
svf
bin_PROGRAMS = \
jtag \
@ -50,7 +51,8 @@ jtag_DEPENDENCIES = \
tap/libtap.a \
part/libpart.a \
bus/libbus.a \
cmd/libcmd.a
cmd/libcmd.a \
svf/libsvf.a
jtag_LDADD = \
-Ltap -ltap \
@ -60,6 +62,7 @@ jtag_LDADD = \
-Lcmd -lcmd \
-L../libbrux -lbrux \
-Lbus -lbus \
-Lsvf -lsvf \
@LIBINTL@
localedir = $(datadir)/locale

@ -51,6 +51,7 @@ libcmd_a_SOURCES = \
eraseflash.c \
script.c \
include.c \
cmd.c
cmd.c \
svf.c
INCLUDES = -DJTAG_DATA_DIR=\"$(pkgdatadir)\"

@ -60,6 +60,7 @@ extern cmd_t cmd_flashmem;
extern cmd_t cmd_eraseflash;
extern cmd_t cmd_script;
extern cmd_t cmd_include;
extern cmd_t cmd_svf;
const cmd_t *cmds[] = {
&cmd_quit,
@ -91,6 +92,7 @@ const cmd_t *cmds[] = {
&cmd_eraseflash,
&cmd_script,
&cmd_include,
&cmd_svf,
NULL /* last must be NULL */
};

@ -0,0 +1,91 @@
/*
* $Id$
*
* Copyright (C) 2004, Arnim Laeuger
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by Arnim Laeuger <arniml@users.sourceforge.net>, 2004.
*
*/
#include "sysdep.h"
#include <stdio.h>
#include <string.h>
#include <svf.h>
#include <cmd.h>
static int
cmd_svf_run( char *params[] )
{
FILE *SVF_FILE;
int num_params, result = -1;
num_params = cmd_params( params );
if (num_params == 2 || num_params == 3) {
if ((SVF_FILE = fopen(params[1], "r")) != NULL) {
if (num_params == 3) {
if (strcmp(params[2], "stop") == 0) {
svf_run(SVF_FILE, 1);
result = 1;
}
} else {
svf_run(SVF_FILE, 0);
result = 1;
}
fclose(SVF_FILE);
} else {
printf( _("%s: cannot open file '%s' for reading\n"), "svf", params[1] );
}
}
return result;
}
static void
cmd_svf_help( void )
{
printf( _(
"Usage: %s FILE\n"
"Usage: %s FILE stop\n"
"Execute svf commands from FILE.\n"
"Command execution stops upon TDO mismatch when 'stop' is specified.\n"
"\n"
"FILE file containing SVF commans\n"
), "svf", "svf" );
}
cmd_t cmd_svf = {
"svf",
N_("execute svf commands from file"),
cmd_svf_help,
cmd_svf_run
};
/* Emacs specific variables
;;; Local Variables: ***
;;; indent-tabs-mode:t ***
;;; tab-width:2 ***
;;; End: ***
*/

@ -0,0 +1,38 @@
#
# $Id: Makefile.am,v 1.16 2003/09/14 20:04:24 telka Exp $
#
# Copyright (C) 2002 ETC s.r.o.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#
# Written by Marcel Telka <marcel@telka.sk>, 2002.
#
include $(top_srcdir)/Makefile.rules
noinst_LIBRARIES = libsvf.a
libsvf_a_SOURCES = \
svf_bison.y \
svf_flex.l \
svf.c
AM_YFLAGS = -d
CLEANFILES = \
svf_bison.c \
svf_bison.h \
svf_flex.c

File diff suppressed because it is too large Load Diff

@ -0,0 +1,73 @@
/*
* $Id$
*
* Copyright (C) 2004, Arnim Laeuger
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by Arnim Laeuger <arniml@users.sourceforge.net>, 2004.
*
*/
#define MAX_PATH_STATES 64
/* Coding for commands referring either to IR or DR */
enum generic_irdr_coding { generic_ir, generic_dr };
struct tdval {
int token;
double dvalue;
};
struct tcval {
int token;
char *cvalue;
struct tcval *next;
};
struct ths_params {
double number;
char *tdi;
char *tdo;
char *mask;
char *smask;
};
struct path_states {
int states[MAX_PATH_STATES];
int num_states;
};
struct runtest {
int run_state;
double run_count;
int run_clk;
double min_time;
double max_time;
int end_state;
};
void svf_endxr(enum generic_irdr_coding, int);
void svf_frequency(double);
int svf_hxr(enum generic_irdr_coding, struct ths_params *);
int svf_runtest(struct runtest *);
int svf_state(struct path_states *, int);
int svf_sxr(enum generic_irdr_coding, struct ths_params *);
int svf_trst(int);
int svf_txr(enum generic_irdr_coding, struct ths_params *);

@ -0,0 +1,442 @@
/*
* $Id$
*
* Copyright (C) 2002 by CSD at http://www-csd.ijs.si
* Copyright (C) 2004, Arnim Laeuger
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by Arnim Laeuger <arniml@users.sourceforge.net>, 2004.
* Original parser skeleton by Robert Sedevici <robert.sedevcic@ijs.si>, 2002.
*
*/
%{
#include <stdio.h>
#include <stdlib.h>
#include "svf.h"
#define YYERROR_VERBOSE
struct svf_parser_params {
struct ths_params ths_params;
struct path_states path_states;
struct runtest runtest;
};
static struct svf_parser_params parser_params = {
{0.0, NULL, NULL, NULL, NULL},
{{}, 0},
{0, 0.0, 0, 0, 0, 0}
};
void yyerror(const char *);
int yylex(void);
static void svf_free_ths_params(struct ths_params *);
%}
%union {
int token;
double dvalue;
char *cvalue;
int ivalue;
struct tdval tdval;
struct tcval *tcval;
}
%token IDENTIFIER NUMBER HEXA_NUM VECTOR_STRING
%token EMPTY
%token ENDDR ENDIR
%token FREQUENCY HZ
%token STATE RESET IDLE
%token TDI TDO MASK SMASK
%token TRST ON OFF Z ABSENT
%token HDR HIR SDR SIR TDR TIR
%token PIO PIOMAP IN OUT INOUT H L U D X
%token RUNTEST MAXIMUM SEC TCK SCK ENDSTATE
%token IRPAUSE IRSHIFT IRUPDATE IRSELECT IREXIT1 IREXIT2 IRCAPTURE
%token DRPAUSE DRSHIFT DRUPDATE DRSELECT DREXIT1 DREXIT2 DRCAPTURE
%token SVF_EOF 0 /* SVF_EOF must match bison's token YYEOF */
%type <dvalue> NUMBER
%type <tdval> runtest_clk_count
%type <token> runtest_run_state
%type <token> runtest_end_state
%%
line
: /* empty */
| line svf_statement
| error SVF_EOF
/* Eat whole file in case of error.
* This is necessary because the lexer will remember parts of the file
* inside its input buffer.
* In case errors do not driver the lexer to EOF then the next start
* of yyparse() will read from this buffer, executing commands after the
* previous error!
*/
;
svf_statement
: ENDIR stable_state ';'
{
svf_endxr(generic_ir, $<token>2);
}
| ENDDR stable_state ';'
{
svf_endxr(generic_dr, $<token>2);
}
| FREQUENCY ';'
{
svf_frequency(0.0);
}
| FREQUENCY NUMBER HZ ';'
{
svf_frequency($2);
}
| HDR NUMBER ths_param_list ';'
{
struct ths_params *p = &parser_params.ths_params;
p->number = $2;
svf_hxr(generic_dr, p);
svf_free_ths_params(p);
}
| HIR NUMBER ths_param_list ';'
{
struct ths_params *p = &parser_params.ths_params;
p->number = $2;
svf_hxr(generic_ir, p);
svf_free_ths_params(p);
}
| PIOMAP '(' direction IDENTIFIER piomap_rec ')' ';'
{
printf("PIOMAP not implemented\n");
yyerror("PIOMAP");
YYERROR;
}
| PIO VECTOR_STRING ';'
{
free($<cvalue>2);
printf("PIO not implemented\n");
yyerror("PIO");
YYERROR;
}
| RUNTEST runtest_run_state runtest_clk_count runtest_min_time1 runtest_end_state ';'
{
struct runtest *rt = &parser_params.runtest;
rt->run_state = $2;
rt->run_count = $3.dvalue;
rt->run_clk = $3.token;
rt->end_state = $5;
if (!svf_runtest(rt)) {
yyerror("RUNTEST");
YYERROR;
}
}
| RUNTEST runtest_run_state runtest_min_time2 runtest_max_time runtest_end_state ';'
{
struct runtest *rt = &parser_params.runtest;
rt->run_state = $2;
rt->run_count = 0;
rt->run_clk = 0;
rt->end_state = $5;
if (!svf_runtest(rt)) {
yyerror("RUNTEST");
YYERROR;
}
}
| SDR NUMBER ths_param_list ';'
{
struct ths_params *p = &parser_params.ths_params;
int result;
p->number = $2;
result = svf_sxr(generic_dr, p);
svf_free_ths_params(p);
if (!result) {
yyerror("SDR");
YYERROR;
}
}
| SIR NUMBER ths_param_list ';'
{
struct ths_params *p = &parser_params.ths_params;
int result;
p->number = $2;
result = svf_sxr(generic_ir, p);
svf_free_ths_params(p);
if (!result) {
yyerror("SIR");
YYERROR;
}
}
| STATE path_states stable_state ';'
{
if (!svf_state(&parser_params.path_states, $<token>3)) {
yyerror("STATE");
YYERROR;
}
}
| TDR NUMBER ths_param_list ';'
{
struct ths_params *p = &parser_params.ths_params;
int result;
p->number = $2;
result = svf_txr(generic_dr, p);
svf_free_ths_params(p);
if (!result) {
yyerror("TDR");
YYERROR;
}
}
| TIR NUMBER ths_param_list ';'
{
struct ths_params *p = &parser_params.ths_params;
int result;
p->number = $2;
result = svf_txr(generic_ir, p);
svf_free_ths_params(p);
if (!result) {
yyerror("TIR");
YYERROR;
}
}
| TRST trst_mode ';'
{
if (!svf_trst($<token>2)) {
yyerror("TRST");
YYERROR;
}
}
;
ths_param_list
: /* empty element */
| ths_param_list ths_opt_param
;
ths_opt_param
: TDI HEXA_NUM
{
parser_params.ths_params.tdi = $<cvalue>2;
}
| TDO HEXA_NUM
{
parser_params.ths_params.tdo = $<cvalue>2;
}
| MASK HEXA_NUM
{
parser_params.ths_params.mask = $<cvalue>2;
}
| SMASK HEXA_NUM
{
parser_params.ths_params.smask = $<cvalue>2;
}
;
stable_state
: RESET
| IDLE
| DRPAUSE
| IRPAUSE
;
runtest_run_state
: { $$ = 0; } /* specify value for 'not existing' */
| stable_state
{
$$ = $<token>1;
}
;
runtest_clk_count
: NUMBER TCK
{
$$.token = $<token>2;
$$.dvalue = $<dvalue>1;
}
| NUMBER SCK
{
$$.token = $<token>2;
$$.dvalue = $<dvalue>1;
}
;
runtest_min_time1
:
{
parser_params.runtest.min_time = 0.0;
parser_params.runtest.max_time = 0.0;
}
| NUMBER SEC runtest_max_time
{
parser_params.runtest.min_time = $<dvalue>1;
}
;
runtest_min_time2
: NUMBER SEC
{
parser_params.runtest.min_time = $<dvalue>1;
}
;
runtest_max_time
:
| MAXIMUM NUMBER SEC
{
parser_params.runtest.max_time = $<dvalue>2;
}
;
runtest_end_state
: { $$ = 0; } /* specify value for 'not existing' */
| ENDSTATE stable_state
{
$$ = $<token>2;
}
;
all_states
: DRSELECT
| DRCAPTURE
| DRSHIFT
| DREXIT1
| DREXIT2
| DRUPDATE
| IRSELECT
| IRCAPTURE
| IRSHIFT
| IREXIT1
| IREXIT2
| IRUPDATE
| IRPAUSE
| DRPAUSE
| RESET
| IDLE
;
path_states
: /* empty element, returns index 0 */
{
parser_params.path_states.num_states = 0;
}
| path_states all_states
{
struct path_states *ps = &parser_params.path_states;
if (ps->num_states < MAX_PATH_STATES) {
ps->states[ps->num_states] = $<token>2;
ps->num_states++;
} else
printf("Error %s: maximum number of %d path states reached.\n",
"svf", MAX_PATH_STATES);
}
;
piomap_rec
:
| piomap_rec direction IDENTIFIER
;
trst_mode
: ON
| OFF
| Z
| ABSENT
;
direction
: IN
| OUT
| INOUT
;
%%
void
yyerror(const char *error_string)
{
printf("Error occured for SVF command %s.\n", error_string);
}
static void
svf_free_ths_params(struct ths_params *params)
{
params->number = 0.0;
if (params->tdi) {
free(params->tdi);
params->tdi = NULL;
}
if (params->tdo) {
free(params->tdo);
params->tdo = NULL;
}
if (params->mask) {
free(params->mask);
params->mask = NULL;
}
if (params->smask) {
free(params->smask);
params->smask = NULL;
}
}

@ -0,0 +1,260 @@
/* $Id$
*
* Copyright (C) 2002 by CSD at http://www-csd.ijs.si
* Copyright (C) 2004, Arnim Laeuger
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Original lexer by Robert Sedevici <robert.sedevcic@ijs.si>, 2002.
* Modified by Arnim Laeuger <arniml@users.sourceforge.net>, 2004.
*
*/
%{
#include <strings.h>
#include <ctype.h>
#include "svf.h"
#include "svf_bison.h"
static int map_keyw_ident(void);
static void align_string(char *);
int yywrap(void)
{
return(1);
}
%}
%pointer
LETTER [A-Za-z]
DIGIT [0-9]
HEX_DIGIT {DIGIT}|[a-fA-F]
WSPACE [ \t\r]
COMMENT (!.*)|("//".*)[^\n]
%s expect_vector
%%
{LETTER}+[0-9A-Za-z_]* {
/* token is a keyword or identifier */
int keyw;
keyw = map_keyw_ident();
/* enable detection of VECTOR_STRING when this is a PIO command */
if (keyw == PIO) {
BEGIN(expect_vector);
}
return(keyw);
} /* end of keyword or identifier */
{DIGIT}+(\.{DIGIT}+)?([eE][-+]?{DIGIT}+)? {
/* token is a real number */
yylval.dvalue = strtod(yytext, (char **) NULL);
return(NUMBER);
} /* end of real number */
<expect_vector>"("{WSPACE}*[\n\rHhLlZzUuDdXx \t\r]+{WSPACE}*")" {
/* There is a overlap of VECTOR_STRING and HEXA_NUM when the string
contains only 'd' or 'D'. To prevent complicated parsing rules,
the lexer is instructed to detect VECTOR_STRING only when a PIO
command has been scanned previously.
This is enabled with <expect_vector>. */
/* token is a vector string */
char *cstring;
align_string(yytext);
cstring = calloc(strlen(yytext) + 1, sizeof(char));
strcpy(cstring, yytext);
yylval.cvalue = cstring;
return(VECTOR_STRING);
} /* end of vector string */
"("{WSPACE}*[\n\rA-Fa-f0-9 \t\r]+{WSPACE}*")" {
/* token is a hexadecimal value (2) */
char *cstring;
align_string(yytext);
cstring = calloc(strlen(yytext) + 1, sizeof(char));
strcpy(cstring, yytext);
yylval.cvalue = cstring;
return(HEXA_NUM);
} /* end of hexadecimal value */
{WSPACE}+ {
/* token is a white space character */
} /* end of white space */
{COMMENT} {
/* token is a comment */
} /* end of comment */
[()] {
/* left or right parenthes */
return(yytext[0]);
} /* end of left or right parenthesis */
\n {
/* token is a new line character */
} /* end of new line */
; {
/* token is end of statement character */
/* release expect_vector */
BEGIN(INITIAL);
return(yytext[0]);
} /* end of statement character */
<<EOF>> {
return(EOF);
} /* end of file token */
. {
/* print token if interactive parsing enabled and yyin != stdin */
fprintf(stderr, "Error: \"%s\" is not a legal SVF language token\n", yytext);
} /* end of any other character */
%%
/*=============================================================================
* rwtable - reserve word table
*===========================================================================*/
static struct rwtable
{
char *rw_name;
int rw_yylex;
} rwtable[] = {
{"ABSENT", ABSENT},
{"D", D},
{"DRCAPTURE", DRCAPTURE},
{"DREXIT1", DREXIT1},
{"DREXIT2", DREXIT2},
{"DRPAUSE", DRPAUSE},
{"DRSELECT", DRSELECT},
{"DRSHIFT", DRSHIFT},
{"DRUPDATE", DRUPDATE},
{"EMPTY", EMPTY},
{"ENDDR", ENDDR},
{"ENDIR", ENDIR},
{"ENDSTATE", ENDSTATE},
{"FREQUENCY", FREQUENCY},
{"H", H},
{"HDR", HDR},
{"HIR", HIR},
{"HZ", HZ},
{"IDLE", IDLE},
{"IN", IN},
{"INOUT", INOUT},
{"IRCAPTURE", IRCAPTURE},
{"IREXIT1", IREXIT1},
{"IREXIT2", IREXIT2},
{"IRPAUSE", IRPAUSE},
{"IRSELECT", IRSELECT},
{"IRSHIFT", IRSHIFT},
{"IRUPDATE", IRUPDATE},
{"L", L},
{"MASK", MASK},
{"MAXIMUM", MAXIMUM},
{"OFF", OFF},
{"ON", ON},
{"OUT", OUT},
{"PIO", PIO},
{"PIOMAP", PIOMAP},
{"RESET", RESET},
{"RUNTEST", RUNTEST},
{"SCK", SCK},
{"SDR", SDR},
{"SEC", SEC},
{"SIR", SIR},
{"SMASK", SMASK},
{"STATE", STATE},
{"TCK", TCK},
{"TDI", TDI},
{"TDO", TDO},
{"TDR", TDR},
{"TIR", TIR},
{"TRST", TRST},
{"U", U},
{"X", X},
{"Z", Z}
};//end of rwtable struct
#define END(v) (sizeof(v) / sizeof(v[0]) - 1)
static int
map_keyw_ident(void)
{
int idx;
int rw = IDENTIFIER;
yylval.cvalue = yytext;
for (idx = 0; idx <= END(rwtable); idx++) {
if (strcasecmp(rwtable[idx].rw_name, yytext) == 0) {
/* always return terminal value as semantic value */
rw = rwtable[idx].rw_yylex;
yylval.token = rw;
}
}
return(rw);
}
static void
align_string(char *str)
{
int src, dst, len;
dst = 0;
len = strlen(str);
for (src = 0; src < len; src++) {
if (isxdigit(str[src]))
str[dst++] = str[src];
}
str[dst] = '\0';
}

@ -95,7 +95,7 @@ chain_get_trst( chain_t *chain )
}
void
chain_shift_instructions( chain_t *chain )
chain_shift_instructions_mode( chain_t *chain, int capture, int exit )
{
int i;
parts_t *ps;
@ -112,13 +112,21 @@ chain_shift_instructions( chain_t *chain )
}
}
tap_capture_ir( chain );
if (capture)
tap_capture_ir( chain );
for (i = 0; i < ps->len; i++)
tap_shift_register( chain, ps->parts[i]->active_instruction->value, NULL, (i + 1) == ps->len );
tap_shift_register( chain, ps->parts[i]->active_instruction->value, NULL,
(i + 1) == ps->len ? exit : EXITMODE_SHIFT );
}
void
chain_shift_data_registers( chain_t *chain, int capture_output )
chain_shift_instructions( chain_t *chain )
{
chain_shift_instructions_mode( chain, 1, EXITMODE_IDLE );
}
void
chain_shift_data_registers_mode( chain_t *chain, int capture_output, int capture, int exit )
{
int i;
parts_t *ps;
@ -139,9 +147,16 @@ chain_shift_data_registers( chain_t *chain, int capture_output )
}
}
tap_capture_dr( chain );
if (capture)
tap_capture_dr( chain );
for (i = 0; i < ps->len; i++)
tap_shift_register( chain, ps->parts[i]->active_instruction->data_register->in,
capture_output ? ps->parts[i]->active_instruction->data_register->out : NULL,
(i + 1) == ps->len );
(i + 1) == ps->len ? exit : EXITMODE_SHIFT );
}
void
chain_shift_data_registers( chain_t *chain, int capture_output )
{
chain_shift_data_registers_mode( chain, capture_output, 1, EXITMODE_IDLE );
}

@ -59,10 +59,10 @@ tap_shift_register( chain_t *chain, const tap_register *in, tap_register *out, i
for (i = 0; i < in->len; i++) {
if (out && (i < out->len))
out->data[i] = cable_get_tdo( chain->cable );
chain_clock( chain, (exit && ((i + 1) == in->len)) ? 1 : 0, in->data[i] ); /* Shift (& Exit1) */
chain_clock( chain, (exit != EXITMODE_SHIFT && ((i + 1) == in->len)) ? 1 : 0, in->data[i] ); /* Shift (& Exit1) */
}
/* Shift-DR, Shift-IR, Exit1-DR or Exit1-IR state */
if (exit) {
if (exit == EXITMODE_IDLE) {
chain_clock( chain, 1, 0 ); /* Update-DR or Update-IR */
chain_clock( chain, 0, 0 ); /* Run-Test/Idle */
}

Loading…
Cancel
Save