Added initial TAP implementation.
git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@66 b68d4a1b-bc3d-0410-92ed-d4ac073336b7master
parent
36debc14fb
commit
2513cb95e6
@ -0,0 +1,3 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
@ -0,0 +1,32 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
noinst_LIBRARIES = libtap.a
|
||||
|
||||
libtap_a_SOURCES = \
|
||||
ctrl.c \
|
||||
tap.c \
|
||||
register.c \
|
||||
state.c
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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 <sys/io.h>
|
||||
|
||||
#include <jtag/ctrl.h>
|
||||
#include <jtag/state.h>
|
||||
|
||||
#define TCK 0
|
||||
#define TDI 1
|
||||
#define TMS 2
|
||||
#define TRST 4
|
||||
|
||||
#define TDO 7
|
||||
|
||||
static unsigned short int port = 0x378;
|
||||
|
||||
void
|
||||
tap_init( void )
|
||||
{
|
||||
tap_state_init();
|
||||
ioperm( port, 2, 1 );
|
||||
tap_state_set_trst( (inb( port ) >> TRST) & 1 );
|
||||
}
|
||||
|
||||
void
|
||||
tap_done( void )
|
||||
{
|
||||
ioperm( port, 2, 0 );
|
||||
|
||||
tap_state_done();
|
||||
}
|
||||
|
||||
void
|
||||
tap_clock( int tms, int tdi )
|
||||
{
|
||||
int trst = tap_state_get_trst();
|
||||
|
||||
tms &= 1;
|
||||
tdi &= 1;
|
||||
|
||||
outb( (trst << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port );
|
||||
outb( (trst << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port );
|
||||
|
||||
tap_state_clock( tms );
|
||||
}
|
||||
|
||||
int
|
||||
tap_get_tdo( void )
|
||||
{
|
||||
outb( (tap_state_get_trst() << TRST) | (0 << TCK), port );
|
||||
return ((inb( port + 1 ) >> TDO) & 1) ^ 1;
|
||||
}
|
||||
|
||||
void
|
||||
tap_set_trst( int new_trst )
|
||||
{
|
||||
tap_state_set_trst( new_trst );
|
||||
outb( (new_trst & 1) << TRST, port );
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <jtag/register.h>
|
||||
|
||||
tap_register *
|
||||
register_alloc( int len )
|
||||
{
|
||||
tap_register *tr;
|
||||
|
||||
if (len < 1)
|
||||
return NULL;
|
||||
|
||||
tr = malloc( sizeof (tap_register) );
|
||||
if (!tr)
|
||||
return NULL;
|
||||
|
||||
tr->data = malloc( len );
|
||||
if (!tr->data) {
|
||||
free( tr );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tr->string = malloc( len + 1 );
|
||||
if (!tr->string) {
|
||||
free( tr->data );
|
||||
free( tr );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tr->len = len;
|
||||
tr->string[len] = '\0';
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
void
|
||||
register_free( tap_register *tr )
|
||||
{
|
||||
if (tr) {
|
||||
free( tr->data );
|
||||
free( tr->string );
|
||||
}
|
||||
free( tr );
|
||||
}
|
||||
|
||||
tap_register *
|
||||
register_fill( tap_register *tr, int val )
|
||||
{
|
||||
if (tr)
|
||||
memset( tr->data, val & 1, tr->len );
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
const char *
|
||||
register_get_string( tap_register *tr )
|
||||
{
|
||||
if (tr) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tr->len; i++)
|
||||
tr->string[tr->len - 1 - i] = (tr->data[i] & 1) ? '1' : '0';
|
||||
}
|
||||
|
||||
return tr->string;
|
||||
}
|
||||
|
||||
tap_register *
|
||||
register_init( tap_register *tr, const char *value )
|
||||
{
|
||||
int i;
|
||||
|
||||
const char *p;
|
||||
|
||||
if (!value || !tr)
|
||||
return tr;
|
||||
|
||||
p = strchr( value, '\0' );
|
||||
|
||||
for (i = 0; i < tr->len; i++) {
|
||||
if (p == value)
|
||||
tr->data[i] = 0;
|
||||
else {
|
||||
p--;
|
||||
tr->data[i] = (*p == '0') ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
int
|
||||
register_compare( const tap_register *tr, const tap_register *tr2 )
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!tr && !tr2)
|
||||
return 0;
|
||||
|
||||
if (!tr || !tr2)
|
||||
return 1;
|
||||
|
||||
if (tr->len != tr2->len)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < tr->len; i++)
|
||||
if (tr->data[i] != tr2->data[i])
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* TAP state handling
|
||||
* 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 <jtag/state.h>
|
||||
|
||||
static int state = Unknown_State;
|
||||
static int trst = 0;
|
||||
|
||||
int
|
||||
tap_state( void )
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
int
|
||||
tap_state_init( void )
|
||||
{
|
||||
return state = Unknown_State;
|
||||
}
|
||||
|
||||
int
|
||||
tap_state_done( void )
|
||||
{
|
||||
return state = Unknown_State;
|
||||
}
|
||||
|
||||
int
|
||||
tap_state_set_trst( int new_trst )
|
||||
{
|
||||
if (trst != (new_trst & 1)) {
|
||||
if (trst)
|
||||
state = Unknown_State;
|
||||
else
|
||||
state = Test_Logic_Reset;
|
||||
|
||||
trst = new_trst & 1;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
int
|
||||
tap_state_clock( int tms )
|
||||
{
|
||||
if (tms & 1) {
|
||||
switch (state) {
|
||||
case Test_Logic_Reset:
|
||||
break;
|
||||
case Run_Test_Idle:
|
||||
case Update_DR:
|
||||
case Update_IR:
|
||||
state = Select_DR_Scan;
|
||||
break;
|
||||
case Select_DR_Scan:
|
||||
state = Select_IR_Scan;
|
||||
break;
|
||||
case Capture_DR:
|
||||
case Shift_DR:
|
||||
state = Exit1_DR;
|
||||
break;
|
||||
case Exit1_DR:
|
||||
case Exit2_DR:
|
||||
state = Update_DR;
|
||||
break;
|
||||
case Pause_DR:
|
||||
state = Exit2_DR;
|
||||
break;
|
||||
case Select_IR_Scan:
|
||||
state = Test_Logic_Reset;
|
||||
break;
|
||||
case Capture_IR:
|
||||
case Shift_IR:
|
||||
state = Exit1_IR;
|
||||
break;
|
||||
case Exit1_IR:
|
||||
case Exit2_IR:
|
||||
state = Update_IR;
|
||||
break;
|
||||
case Pause_IR:
|
||||
state = Exit2_IR;
|
||||
break;
|
||||
default:
|
||||
state = Unknown_State;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (state) {
|
||||
case Test_Logic_Reset:
|
||||
case Run_Test_Idle:
|
||||
case Update_DR:
|
||||
case Update_IR:
|
||||
state = Run_Test_Idle;
|
||||
break;
|
||||
case Select_DR_Scan:
|
||||
state = Capture_DR;
|
||||
break;
|
||||
case Capture_DR:
|
||||
case Shift_DR:
|
||||
case Exit2_DR:
|
||||
state = Shift_DR;
|
||||
break;
|
||||
case Exit1_DR:
|
||||
case Pause_DR:
|
||||
state = Pause_DR;
|
||||
break;
|
||||
case Select_IR_Scan:
|
||||
state = Capture_IR;
|
||||
break;
|
||||
case Capture_IR:
|
||||
case Shift_IR:
|
||||
case Exit2_IR:
|
||||
state = Shift_IR;
|
||||
break;
|
||||
case Exit1_IR:
|
||||
case Pause_IR:
|
||||
state = Pause_IR;
|
||||
break;
|
||||
default:
|
||||
state = Unknown_State;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#include <jtag/register.h>
|
||||
#include <jtag/tap.h>
|
||||
#include <jtag/ctrl.h>
|
||||
#include <jtag/state.h>
|
||||
|
||||
void
|
||||
tap_reset( void )
|
||||
{
|
||||
tap_clock( 1, 0 );
|
||||
tap_clock( 1, 0 );
|
||||
tap_clock( 1, 0 );
|
||||
tap_clock( 1, 0 );
|
||||
tap_clock( 1, 0 ); /* Test-Logic-Reset */
|
||||
|
||||
tap_clock( 0, 0 ); /* Run-Test/Idle */
|
||||
}
|
||||
|
||||
void
|
||||
tap_shift_register( const tap_register *in, tap_register *out, int exit )
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Capture-DR, Capture-IR, Shift-DR, Shift-IR, Exit2-DR or Exit2-IR state */
|
||||
if (tap_state() & TAPSTAT_CAPTURE)
|
||||
tap_clock( 0, 0 ); /* save last TDO bit :-) */
|
||||
for (i = 0; i < in->len; i++) {
|
||||
if (out && (i < out->len))
|
||||
out->data[i] = tap_get_tdo();
|
||||
tap_clock( (exit && ((i + 1) == in->len)) ? 1 : 0, in->data[i] ); /* Shift (& Exit1) */
|
||||
}
|
||||
/* Shift-DR, Shift-IR, Exit1-DR or Exit1-IR state */
|
||||
if (exit)
|
||||
tap_clock( 1, 0 ); /* Update-DR or Update-IR */
|
||||
}
|
||||
|
||||
void
|
||||
tap_capture_dr( void )
|
||||
{
|
||||
/* Run-Test/Idle or Update-DR or Update-IR state */
|
||||
tap_clock( 1, 0 ); /* Select-DR-Scan */
|
||||
tap_clock( 0, 0 ); /* Capture-DR */
|
||||
}
|
||||
|
||||
void
|
||||
tap_capture_ir( void )
|
||||
{
|
||||
/* Run-Test/Idle or Update-DR or Update-IR state */
|
||||
tap_clock( 1, 0 ); /* Select-DR-Scan */
|
||||
tap_clock( 1, 0 ); /* Select-IR-Scan */
|
||||
tap_clock( 0, 0 ); /* Capture-IR */
|
||||
}
|
||||
|
||||
void
|
||||
write_command( const tap_register *c, tap_register *cout, int len )
|
||||
{
|
||||
tap_capture_ir();
|
||||
tap_shift_register( c, cout, 1 );
|
||||
}
|
Loading…
Reference in New Issue