From 2513cb95e65de680ee09577e79f27d593d58387a Mon Sep 17 00:00:00 2001 From: Marcel Telka Date: Mon, 22 Jul 2002 20:39:20 +0000 Subject: [PATCH] Added initial TAP implementation. git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@66 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- jtag/src/tap/.cvsignore | 3 + jtag/src/tap/Makefile.am | 32 +++++++++ jtag/src/tap/ctrl.c | 81 +++++++++++++++++++++ jtag/src/tap/register.c | 136 ++++++++++++++++++++++++++++++++++++ jtag/src/tap/state.c | 147 +++++++++++++++++++++++++++++++++++++++ jtag/src/tap/tap.c | 84 ++++++++++++++++++++++ 6 files changed, 483 insertions(+) create mode 100644 jtag/src/tap/.cvsignore create mode 100644 jtag/src/tap/Makefile.am create mode 100644 jtag/src/tap/ctrl.c create mode 100644 jtag/src/tap/register.c create mode 100644 jtag/src/tap/state.c create mode 100644 jtag/src/tap/tap.c diff --git a/jtag/src/tap/.cvsignore b/jtag/src/tap/.cvsignore new file mode 100644 index 00000000..051d1bd5 --- /dev/null +++ b/jtag/src/tap/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +.deps diff --git a/jtag/src/tap/Makefile.am b/jtag/src/tap/Makefile.am new file mode 100644 index 00000000..83572dd9 --- /dev/null +++ b/jtag/src/tap/Makefile.am @@ -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 , 2002. +# + +noinst_LIBRARIES = libtap.a + +libtap_a_SOURCES = \ + ctrl.c \ + tap.c \ + register.c \ + state.c + +INCLUDES = -I$(top_srcdir)/include diff --git a/jtag/src/tap/ctrl.c b/jtag/src/tap/ctrl.c new file mode 100644 index 00000000..0210085c --- /dev/null +++ b/jtag/src/tap/ctrl.c @@ -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 , 2002. + * + */ + +#include + +#include +#include + +#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 ); +} diff --git a/jtag/src/tap/register.c b/jtag/src/tap/register.c new file mode 100644 index 00000000..a7bc2d24 --- /dev/null +++ b/jtag/src/tap/register.c @@ -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 , 2002. + * + */ + +#include +#include + +#include + +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; +} diff --git a/jtag/src/tap/state.c b/jtag/src/tap/state.c new file mode 100644 index 00000000..e2c3ebdc --- /dev/null +++ b/jtag/src/tap/state.c @@ -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 , 2002. + * + */ + +#include + +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; +} diff --git a/jtag/src/tap/tap.c b/jtag/src/tap/tap.c new file mode 100644 index 00000000..ce2f520d --- /dev/null +++ b/jtag/src/tap/tap.c @@ -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 , 2002. + * + */ + +#include + +#include +#include +#include +#include + +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 ); +}