2003-03-18 Marcel Telka <marcel@telka.sk>

* include/parport.h: New file. Added parport driver support.
		All cable drivers modified.
	* src/tap/parport.c: Ditto.
	* src/tap/parport/direct.c: Ditto.
	* src/jtag.c (jtag_parse_line) <cable>: Added parport driver support.
	* include/Makefile.am (noinst_HEADERS): Added parport.h.
	* src/tap/cable/generic.c: New file withgGeneric functions for cable drivers.
		All cable drivers modified.
	* src/tap/cable/generic.h: Ditto.
	* src/tap/Makefile.am (libtap_a_SOURCES): Added parport.c, parport/direct.c, cable/generic.h,
		and cable/generic.c.

	* include/cable.h: Added dynamic cable objects. Added cable interpose functions.
		All callers changed.
	* src/tap/cable.c: Ditto.

	* include/chain.h (chain_connect): Function removed.
	(chain_disconnect): New function.
	* src/tap/chain.c (chain_free): Modified for chain_disconnect() call.
	(chain_connect): Removed.
	(chain_disconnect): New function.


git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@397 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Marcel Telka 22 years ago
parent 5c062c7022
commit 9406ed47c7

@ -1,3 +1,27 @@
2003-03-18 Marcel Telka <marcel@telka.sk>
* include/parport.h: New file. Added parport driver support.
All cable drivers modified.
* src/tap/parport.c: Ditto.
* src/tap/parport/direct.c: Ditto.
* src/jtag.c (jtag_parse_line) <cable>: Added parport driver support.
* include/Makefile.am (noinst_HEADERS): Added parport.h.
* src/tap/cable/generic.c: New file withgGeneric functions for cable drivers.
All cable drivers modified.
* src/tap/cable/generic.h: Ditto.
* src/tap/Makefile.am (libtap_a_SOURCES): Added parport.c, parport/direct.c, cable/generic.h,
and cable/generic.c.
* include/cable.h: Added dynamic cable objects. Added cable interpose functions.
All callers changed.
* src/tap/cable.c: Ditto.
* include/chain.h (chain_connect): Function removed.
(chain_disconnect): New function.
* src/tap/chain.c (chain_free): Modified for chain_disconnect() call.
(chain_connect): Removed.
(chain_disconnect): New function.
2003-03-17 Marcel Telka <marcel@telka.sk>
* src/Makefile.am (bin_PROGRAMS, bsdl2jtag_SOURCES): Added new bsdl2jtag conversion

@ -29,6 +29,7 @@ noinst_HEADERS = \
data_register.h \
gettext.h \
instruction.h \
parport.h \
part.h \
register.h \
signal.h \

@ -28,18 +28,41 @@
#include <stdint.h>
#define cable_t cable_driver_t
typedef struct cable_t cable_t;
typedef struct {
#include "parport.h"
#include "chain.h"
typedef struct cable_driver_t cable_driver_t;
struct cable_driver_t {
const char *name;
const char *description;
int (*init)( unsigned int );
void (*done)( void );
void (*clock)( int, int );
int (*get_tdo)( void );
int (*set_trst)( int );
int (*get_trst)( void );
} cable_driver_t;
cable_t *(*connect)( cable_driver_t *, parport_t * );
void (*disconnect)( cable_t *cable );
void (*cable_free)( cable_t *cable );
int (*init)( cable_t * );
void (*done)( cable_t * );
void (*clock)( cable_t *, int, int );
int (*get_tdo)( cable_t * );
int (*set_trst)( cable_t *, int );
int (*get_trst)( cable_t * );
};
struct cable_t {
cable_driver_t *driver;
parport_t *port;
void *params;
chain_t *chain;
};
void cable_free( cable_t *cable );
int cable_init( cable_t *cable );
void cable_done( cable_t *cable );
void cable_clock( cable_t *cable, int tms, int tdi );
int cable_get_tdo( cable_t *cable );
int cable_set_trst( cable_t *cable, int trst );
int cable_get_trst( cable_t *cable );
extern uint32_t frequency;
void cable_wait( void );

@ -25,18 +25,21 @@
#ifndef CHAIN_H
#define CHAIN_H
#include "cable.h"
#include "part.h"
typedef struct {
typedef struct chain_t chain_t;
#include "cable.h"
struct chain_t {
int state;
parts_t *parts;
cable_t *cable;
} chain_t;
};
chain_t *chain_alloc( void );
void chain_free( chain_t *chain );
int chain_connect( chain_t *chain, cable_t *cable, unsigned int port );
void chain_disconnect( chain_t *chain );
void chain_clock( chain_t *chain, int tms, int tdi );
int chain_set_trst( chain_t *chain, int trst );
int chain_get_trst( chain_t *chain );

@ -0,0 +1,62 @@
/*
* $Id$
*
* Parallel Port Connection Driver Interface
* Copyright (C) 2003 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>, 2003.
*
*/
#ifndef PARPORT_H
#define PARPORT_H
#include <stdint.h>
typedef struct parport_t parport_t;
#include "cable.h"
typedef struct {
const char *type;
cable_t *(*connect)( const char **, int );
void (*parport_free)( parport_t * );
int (*open)( parport_t * );
int (*close)( parport_t * );
int (*set_data)( parport_t *, uint8_t );
int (*get_data)( parport_t * );
int (*get_status)( parport_t * );
int (*set_control)( parport_t *, uint8_t );
} parport_driver_t;
struct parport_t {
parport_driver_t *driver;
void *params;
cable_t *cable;
};
int parport_open( parport_t *port );
int parport_close( parport_t *port );
int parport_set_data( parport_t *port, uint8_t data );
int parport_get_data( parport_t *port );
int parport_get_status( parport_t *port );
int parport_set_control( parport_t *port, uint8_t data );
extern parport_driver_t *parport_drivers[];
#endif /* PARPORT_H */

@ -41,6 +41,7 @@
#include "part.h"
#include "tap.h"
#include "parport.h"
#include "bus.h"
@ -193,60 +194,43 @@ jtag_parse_line( char *line )
if (strcmp( t, "cable" ) == 0) {
int i;
unsigned int port;
const char *params[10];
int numpar;
t = get_token( NULL );
if (!t) {
printf( _("Missing argument(s)\n") );
return 1;
}
if (strcmp( t, "parallel" ) != 0) {
printf( _("syntax error!\n") );
return 1;
}
t = get_token( NULL );
if (!t) {
printf( _("Missing argument(s)\n") );
return 1;
}
if ((sscanf( t, "0x%x", &port ) != 1) && (sscanf( t, "%d", &port ) != 1)) {
printf( _("syntax error\n") );
for (i = 0; parport_drivers[i]; i++)
if (strcmp( t, parport_drivers[i]->type ) == 0)
break;
if (!parport_drivers[i]) {
printf( _("Unknown connection type: %s\n"), t );
return 1;
}
t = get_token( NULL );
if (!t) {
printf( _("Missing argument(s)\n") );
return 1;
for (numpar = 0; numpar < 10; numpar++) {
params[numpar] = get_token( NULL );
if (!params[numpar])
break;
}
if (get_token( NULL )) {
printf( _("syntax error!\n") );
return 1;
}
if (strcmp( t, "none" ) == 0) {
chain_connect( chain, NULL, 0 );
printf( _("Cable disconnected\n") );
return 1;
}
for (i = 0; cable_drivers[i]; i++)
if (strcmp( t, cable_drivers[i]->name ) == 0)
break;
if (!cable_drivers[i]) {
printf( _("Unknown cable: %s\n"), t );
chain->cable = parport_drivers[i]->connect( params, numpar );
if (!chain->cable) {
printf( _("Error: Cable connection failed!\n") );
return 1;
}
printf( _("Initializing %s on parallel port at 0x%x\n"), cable_drivers[i]->description, port );
if (chain_connect( chain, cable_drivers[i], port )) {
printf( _("Error: Cable driver initialization failed!\n") );
if (cable_init( chain->cable )) {
printf( _("Error: Cable initialization failed!\n") );
chain_disconnect( chain );
return 1;
}
chain_set_trst( chain, 0 );
chain_set_trst( chain, 1 );
tap_reset( chain );

@ -28,7 +28,11 @@ libtap_a_SOURCES = \
register.c \
state.c \
chain.c \
parport.c \
parport/direct.c \
cable.c \
cable/generic.h \
cable/generic.c \
cable/arcom.c \
cable/byteblaster.c \
cable/dlc5.c \

@ -54,6 +54,48 @@ cable_driver_t *cable_drivers[] = {
NULL /* last must be NULL */
};
void
cable_free( cable_t *cable )
{
cable->driver->cable_free( cable );
}
int
cable_init( cable_t *cable )
{
return cable->driver->init( cable );
}
void
cable_done( cable_t *cable )
{
return cable->driver->done( cable );
}
void
cable_clock( cable_t *cable, int tms, int tdi )
{
cable->driver->clock( cable, tms, tdi );
}
int
cable_get_tdo( cable_t *cable )
{
return cable->driver->get_tdo( cable );
}
int
cable_set_trst( cable_t *cable, int trst )
{
return cable->driver->set_trst( cable, trst );
}
int
cable_get_trst( cable_t *cable )
{
return cable->driver->get_trst( cable );
}
void
cable_wait( void )
{

@ -23,9 +23,11 @@
*
*/
#include <sys/io.h>
#include "cable.h"
#include "parport.h"
#include "chain.h"
#include "generic.h"
/*
* data D[7:0] (pins 9:2)
@ -42,73 +44,65 @@
* 4 - SEL (pin 13)
* 3 - ERROR (pin 15)
*/
#define TDO 7
static int trst;
static unsigned int port;
#define TDO 7
static int
arcom_init( unsigned int aport )
arcom_init( cable_t *cable )
{
port = aport;
if (((port + 2 <= 0x400) && ioperm( port, 2, 1 )) || ((port + 2 > 0x400) && iopl( 3 )))
return 0;
trst = (inb( port ) >> TRST) & 1;
int data;
return 1;
}
if (parport_open( cable->port ))
return -1;
static void
arcom_done( void )
{
if (port + 2 <= 0x400)
ioperm( port, 2, 0 );
else
iopl( 0 );
if ((data = parport_get_data( cable->port )) < 0) {
if (parport_set_data( cable->port, 1 << TRST ))
return -1;
PARAM_TRST(cable) = 1;
} else
PARAM_TRST(cable) = (data >> TRST) & 1;
return 0;
}
static void
arcom_clock( int tms, int tdi )
arcom_clock( cable_t *cable, int tms, int tdi )
{
tms = tms ? 1 : 0;
tdi = tdi ? 1 : 0;
outb( (trst << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
outb( (trst << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
}
static int
arcom_get_tdo( void )
arcom_get_tdo( cable_t *cable )
{
outb( (trst << TRST) | (0 << TCK), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) );
cable_wait();
return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */
return (parport_get_status( cable->port ) >> TDO) & 1;
}
static int
arcom_set_trst( int new_trst )
arcom_set_trst( cable_t *cable, int trst )
{
trst = new_trst ? 1 : 0;
outb( trst << TRST, port );
return trst;
}
PARAM_TRST(cable) = trst ? 1 : 0;
static int
arcom_get_trst( void )
{
return trst;
parport_set_data( cable->port, PARAM_TRST(cable) << TRST );
return PARAM_TRST(cable);
}
cable_driver_t arcom_cable_driver = {
"ARCOM",
"Arcom JTAG Cable",
generic_connect,
generic_disconnect,
generic_cable_free,
arcom_init,
arcom_done,
generic_done,
arcom_clock,
arcom_get_tdo,
arcom_set_trst,
arcom_get_trst
generic_get_trst
};

@ -31,9 +31,11 @@
*
*/
#include <sys/io.h>
#include "cable.h"
#include "parport.h"
#include "chain.h"
#include "generic.h"
/*
* data D[7:0] (pins 9:2)
@ -51,52 +53,39 @@
*/
#define TDO 7
static unsigned int port;
static int
byteblaster_init( unsigned int aport )
byteblaster_init( cable_t *cable )
{
port = aport;
return !(((port + 2 <= 0x400) && ioperm( port, 2, 1 )) || ((port + 2 > 0x400) && iopl( 3 )));
}
if (parport_open( cable->port ))
return -1;
static void
byteblaster_done( void )
{
if (port + 2 <= 0x400)
ioperm( port, 2, 0 );
else
iopl( 0 );
PARAM_TRST(cable) = 1;
return 0;
}
static void
byteblaster_clock( int tms, int tdi )
byteblaster_clock( cable_t *cable, int tms, int tdi )
{
tms = tms ? 1 : 0;
tdi = tdi ? 1 : 0;
outb( (0 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (0 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
outb( (1 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (1 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
}
static int
byteblaster_get_tdo( void )
byteblaster_get_tdo( cable_t *cable )
{
outb( 0 << TCK, port );
parport_set_data( cable->port, 0 << TCK );
cable_wait();
return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */
}
static int
byteblaster_set_trst( int new_trst )
{
return 1;
return (parport_get_status( cable->port ) >> TDO) & 1;
}
static int
byteblaster_get_trst( void )
byteblaster_set_trst( cable_t *cable, int trst )
{
return 1;
}
@ -104,10 +93,13 @@ byteblaster_get_trst( void )
cable_driver_t byteblaster_cable_driver = {
"ByteBlaster",
"Altera ByteBlaster/ByteBlaster II/ByteBlasterMV Parallel Port Download Cable",
generic_connect,
generic_disconnect,
generic_cable_free,
byteblaster_init,
byteblaster_done,
generic_done,
byteblaster_clock,
byteblaster_get_tdo,
byteblaster_set_trst,
byteblaster_get_trst
generic_get_trst
};

@ -27,9 +27,11 @@
*
*/
#include <sys/io.h>
#include "cable.h"
#include "parport.h"
#include "chain.h"
#include "generic.h"
/* see Figure B-1 in [1] */
@ -51,52 +53,39 @@
*/
#define TDO 4
static unsigned int port;
static int
dlc5_init( unsigned int aport )
dlc5_init( cable_t *cable )
{
port = aport;
return !(((port + 2 <= 0x400) && ioperm( port, 2, 1 )) || ((port + 2 > 0x400) && iopl( 3 )));
}
if (parport_open( cable->port ))
return -1;
static void
dlc5_done( void )
{
if (port + 2 <= 0x400)
ioperm( port, 2, 0 );
else
iopl( 0 );
PARAM_TRST(cable) = 1;
return 0;
}
static void
dlc5_clock( int tms, int tdi )
dlc5_clock( cable_t *cable, int tms, int tdi )
{
tms = tms ? 1 : 0;
tdi = tdi ? 1 : 0;
outb( (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
outb( (1 << PROG) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (1 << PROG) | (1 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
}
static int
dlc5_get_tdo( void )
dlc5_get_tdo( cable_t *cable )
{
outb( (1 << PROG) | (0 << TCK), port );
parport_set_data( cable->port, (1 << PROG) | (0 << TCK) );
cable_wait();
return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */
}
static int
dlc5_set_trst( int new_trst )
{
return 1;
return (parport_get_status( cable->port ) >> TDO) & 1;
}
static int
dlc5_get_trst( void )
dlc5_set_trst( cable_t *cable, int trst )
{
return 1;
}
@ -104,10 +93,13 @@ dlc5_get_trst( void )
cable_driver_t dlc5_cable_driver = {
"DLC5",
"Xilinx DLC5 JTAG Parallel Cable III",
generic_connect,
generic_disconnect,
generic_cable_free,
dlc5_init,
dlc5_done,
generic_done,
dlc5_clock,
dlc5_get_tdo,
dlc5_set_trst,
dlc5_get_trst
generic_get_trst
};

@ -23,9 +23,11 @@
*
*/
#include <sys/io.h>
#include "cable.h"
#include "parport.h"
#include "chain.h"
#include "generic.h"
/*
* data D[7:0] (pins 9:2)
@ -44,71 +46,63 @@
*/
#define TDO 4
static int trst;
static unsigned int port;
static int
ea253_init( unsigned int aport )
ea253_init( cable_t *cable )
{
port = aport;
if (((port + 2 <= 0x400) && ioperm( port, 2, 1 )) || ((port + 2 > 0x400) && iopl( 3 )))
return 0;
trst = (inb( port ) >> TRST) & 1;
int data;
return 1;
}
if (parport_open( cable->port ))
return -1;
static void
ea253_done( void )
{
if (port + 2 <= 0x400)
ioperm( port, 2, 0 );
else
iopl( 0 );
if ((data = parport_get_data( cable->port )) < 0) {
if (parport_set_data( cable->port, 1 << TRST ))
return -1;
PARAM_TRST(cable) = 1;
} else
PARAM_TRST(cable) = (data >> TRST) & 1;
return 0;
}
static void
ea253_clock( int tms, int tdi )
ea253_clock( cable_t *cable, int tms, int tdi )
{
tms = tms ? 1 : 0;
tdi = tdi ? 1 : 0;
outb( (trst << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
outb( (trst << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
}
static int
ea253_get_tdo( void )
ea253_get_tdo( cable_t *cable )
{
outb( (trst << TRST) | (0 << TCK), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) );
cable_wait();
return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */
return (parport_get_status( cable->port ) >> TDO) & 1;
}
static int
ea253_set_trst( int new_trst )
ea253_set_trst( cable_t *cable, int trst )
{
trst = new_trst ? 1 : 0;
outb( trst << TRST, port );
return trst;
}
PARAM_TRST(cable) = trst ? 1 : 0;
static int
ea253_get_trst( void )
{
return trst;
parport_set_data( cable->port, PARAM_TRST(cable) << TRST );
return PARAM_TRST(cable);
}
cable_driver_t ea253_cable_driver = {
"EA253",
"ETC EA253 JTAG Cable",
generic_connect,
generic_disconnect,
generic_cable_free,
ea253_init,
ea253_done,
generic_done,
ea253_clock,
ea253_get_tdo,
ea253_set_trst,
ea253_get_trst
generic_get_trst
};

@ -23,10 +23,11 @@
*
*/
#include <stdio.h>
#include <sys/io.h>
#include "cable.h"
#include "parport.h"
#include "chain.h"
#include "generic.h"
/*
* data D[7:0] (pins 9:2)
@ -45,71 +46,63 @@
*/
#define TDO 7
static int trst;
static unsigned int port;
static int
ei012_init( unsigned int aport )
ei012_init( cable_t *cable )
{
port = aport;
if (((port + 2 <= 0x400) && ioperm( port, 2, 1 )) || ((port + 2 > 0x400) && iopl( 3 )))
return 0;
trst = (inb( port ) >> TRST) & 1;
int data;
return 1;
}
if (parport_open( cable->port ))
return -1;
static void
ei012_done( void )
{
if (port + 2 <= 0x400)
ioperm( port, 2, 0 );
else
iopl( 0 );
if ((data = parport_get_data( cable->port )) < 0) {
if (parport_set_data( cable->port, 1 << TRST ))
return -1;
PARAM_TRST(cable) = 1;
} else
PARAM_TRST(cable) = (data >> TRST) & 1;
return 0;
}
static void
ei012_clock( int tms, int tdi )
ei012_clock( cable_t *cable, int tms, int tdi )
{
tms = tms ? 1 : 0;
tdi = tdi ? 1 : 0;
outb( (trst << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
outb( (trst << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
}
static int
ei012_get_tdo( void )
ei012_get_tdo( cable_t *cable )
{
outb( (trst << TRST) | (0 << TCK), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) );
cable_wait();
return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */
return (parport_get_status( cable->port ) >> TDO) & 1;
}
static int
ei012_set_trst( int new_trst )
ei012_set_trst( cable_t *cable, int trst )
{
trst = new_trst ? 1 : 0;
outb( trst << TRST, port );
return trst;
}
PARAM_TRST(cable) = trst ? 1 : 0;
static int
ei012_get_trst( void )
{
return trst;
parport_set_data( cable->port, PARAM_TRST(cable) << TRST );
return PARAM_TRST(cable);
}
cable_driver_t ei012_cable_driver = {
"EI012",
"ETC EI012 JTAG Cable",
generic_connect,
generic_disconnect,
generic_cable_free,
ei012_init,
ei012_done,
generic_done,
ei012_clock,
ei012_get_tdo,
ei012_set_trst,
ei012_get_trst
generic_get_trst
};

@ -0,0 +1,77 @@
/*
* $Id$
*
* Copyright (C) 2003 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>, 2003.
*
*/
#include <stdlib.h>
#include "cable.h"
#include "parport.h"
#include "chain.h"
#include "generic.h"
cable_t *
generic_connect( cable_driver_t *cable_driver, parport_t *port )
{
generic_params_t *params = malloc( sizeof *params );
cable_t *cable = malloc( sizeof *cable );
if (!params || !cable) {
free( params );
free( cable );
return NULL;
}
cable->driver = cable_driver;
cable->port = port;
cable->params = params;
cable->chain = NULL;
return cable;
}
void
generic_disconnect( cable_t *cable )
{
cable_done( cable );
chain_disconnect( cable->chain );
}
void
generic_cable_free( cable_t *cable )
{
cable->port->driver->parport_free( cable->port );
free( cable->params );
free( cable );
}
void
generic_done( cable_t *cable )
{
parport_close( cable->port );
}
int
generic_get_trst( cable_t *cable )
{
return PARAM_TRST(cable);
}

@ -0,0 +1,43 @@
/*
* $Id$
*
* Copyright (C) 2003 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>, 2003.
*
*/
#ifndef GENERIC_H
#define GENERIC_H
#include "cable.h"
#include "parport.h"
typedef struct {
int trst;
} generic_params_t;
#define PARAM_TRST(cable) ((generic_params_t *) cable->params)->trst
cable_t *generic_connect( cable_driver_t *cable_driver, parport_t *port );
void generic_disconnect( cable_t *cable );
void generic_cable_free( cable_t *cable );
void generic_done( cable_t *cable );
int generic_get_trst( cable_t *cable );
#endif /* GENERIC_H */

@ -27,9 +27,11 @@
*
*/
#include <sys/io.h>
#include "cable.h"
#include "parport.h"
#include "chain.h"
#include "generic.h"
/*
* data
@ -49,76 +51,60 @@
*/
#define TDO 5
static int trst;
static unsigned int port;
static int
mpcbdm_init( unsigned int aport )
mpcbdm_init( cable_t *cable )
{
port = aport;
if (((port + 3 <= 0x400) && ioperm( port, 3, 1 )) || ((port + 3 > 0x400) && iopl( 3 )))
return 0;
if (parport_open( cable->port ))
return -1;
outb( (1 << TRST) | (1 << TRST1), port + 2 );
trst = 1;
parport_set_control( cable->port, (1 << TRST) | (1 << TRST1) );
PARAM_TRST(cable) = 1;
return 1;
return 0;
}
static void
mpcbdm_done( void )
{
if (port + 3 <= 0x400)
ioperm( port, 3, 0 );
else
iopl( 0 );
}
static void
mpcbdm_clock( int tms, int tdi )
mpcbdm_clock( cable_t *cable, int tms, int tdi )
{
tms = tms ? 1 : 0;
tdi = tdi ? 1 : 0;
outb( (0 << TCK) | (tms << TMS) | (tdi << TDI), port );
outb( (trst << TRST) | (trst << TRST1), port + 2 );
parport_set_data( cable->port, (0 << TCK) | (tms << TMS) | (tdi << TDI) );
parport_set_control( cable->port, (PARAM_TRST(cable) << TRST) | (PARAM_TRST(cable) << TRST1) );
cable_wait();
outb( (1 << TCK) | (tms << TMS) | (tdi << TDI), port );
outb( (trst << TRST) | (trst << TRST1), port + 2 );
parport_set_data( cable->port, (1 << TCK) | (tms << TMS) | (tdi << TDI) );
parport_set_control( cable->port, (PARAM_TRST(cable) << TRST) | (PARAM_TRST(cable) << TRST1) );
cable_wait();
}
static int
mpcbdm_get_tdo( void )
mpcbdm_get_tdo( cable_t *cable )
{
outb( (0 << TCK), port );
outb( (trst << TRST) | (trst << TRST1), port + 2 );
parport_set_data( cable->port, 0 << TCK );
parport_set_control( cable->port, (PARAM_TRST(cable) << TRST) | (PARAM_TRST(cable) << TRST1) );
cable_wait();
return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */
return (parport_get_status( cable->port ) >> TDO) & 1;
}
static int
mpcbdm_set_trst( int new_trst )
mpcbdm_set_trst( cable_t *cable, int trst )
{
trst = new_trst ? 1 : 0;
outb( (trst << TRST) | (trst << TRST1), port + 2 );
return trst;
}
PARAM_TRST(cable) = trst ? 1 : 0;
static int
mpcdbm_get_trst( void )
{
return trst;
parport_set_control( cable->port, (PARAM_TRST(cable) << TRST) | (PARAM_TRST(cable) << TRST1) );
return PARAM_TRST(cable);
}
cable_driver_t mpcbdm_cable_driver = {
"MPCBDM",
"Mpcbdm JTAG cable",
generic_connect,
generic_disconnect,
generic_cable_free,
mpcbdm_init,
mpcbdm_done,
generic_done,
mpcbdm_clock,
mpcbdm_get_tdo,
mpcbdm_set_trst,
mpcdbm_get_trst
generic_get_trst
};

@ -27,9 +27,11 @@
*
*/
#include <sys/io.h>
#include "cable.h"
#include "parport.h"
#include "chain.h"
#include "generic.h"
/*
* data D[7:0] (pins 9:2)
@ -48,71 +50,63 @@
*/
#define TDO 7
static int trst;
static unsigned int port;
static int
wiggler_init( unsigned int aport )
wiggler_init( cable_t *cable )
{
port = aport;
if (((port + 2 <= 0x400) && ioperm( port, 2, 1 )) || ((port + 2 > 0x400) && iopl( 3 )))
return 0;
trst = (inb( port ) >> TRST) & 1;
int data;
return 1;
}
if (parport_open( cable->port ))
return -1;
static void
wiggler_done( void )
{
if (port + 2 <= 0x400)
ioperm( port, 2, 0 );
else
iopl( 0 );
if ((data = parport_get_data( cable->port )) < 0) {
if (parport_set_data( cable->port, 1 << TRST ))
return -1;
PARAM_TRST(cable) = 1;
} else
PARAM_TRST(cable) = (data >> TRST) & 1;
return 0;
}
static void
wiggler_clock( int tms, int tdi )
wiggler_clock( cable_t *cable, int tms, int tdi )
{
tms = tms ? 1 : 0;
tdi = tdi ? 1 : 0;
outb( (trst << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
outb( (trst << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) );
cable_wait();
}
static int
wiggler_get_tdo( void )
wiggler_get_tdo( cable_t *cable )
{
outb( (trst << TRST) | (0 << TCK), port );
parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) );
cable_wait();
return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */
return (parport_get_status( cable->port ) >> TDO) & 1;
}
static int
wiggler_set_trst( int new_trst )
wiggler_set_trst( cable_t *cable, int trst )
{
trst = new_trst ? 1 : 0;
outb( trst << TRST, port );
return trst;
}
PARAM_TRST(cable) = trst ? 1 : 0;
static int
wiggler_get_trst( void )
{
return trst;
parport_set_data( cable->port, PARAM_TRST(cable) << TRST );
return PARAM_TRST(cable);
}
cable_driver_t wiggler_cable_driver = {
"WIGGLER",
"Macraigor Wiggler JTAG Cable",
generic_connect,
generic_disconnect,
generic_cable_free,
wiggler_init,
wiggler_done,
generic_done,
wiggler_clock,
wiggler_get_tdo,
wiggler_set_trst,
wiggler_get_trst
generic_get_trst
};

@ -57,31 +57,22 @@ chain_free( chain_t *chain )
if (!chain)
return;
if (chain->cable) {
chain->cable->set_trst( 0 );
chain->cable->set_trst( 1 );
tap_reset( chain );
chain->cable->done();
}
tap_state_done( chain );
/* cable_free( chain->cable ); */
chain_disconnect( chain );
parts_free( chain->parts );
free( chain );
}
int
chain_connect( chain_t *chain, cable_t *cable, unsigned int port )
void
chain_disconnect( chain_t *chain )
{
if (chain->cable) {
tap_state_done( chain );
chain->cable->done();
chain->cable = NULL;
}
if (!cable || !cable->init( port ))
return -1;
if (!chain->cable)
return;
chain->cable = cable;
return 0;
tap_state_done( chain );
cable_done( chain->cable );
cable_free( chain->cable );
chain->cable = NULL;
}
void
@ -90,15 +81,15 @@ chain_clock( chain_t *chain, int tms, int tdi )
if (!chain || !chain->cable)
return;
chain->cable->clock( tms, tdi );
cable_clock( chain->cable, tms, tdi );
tap_state_clock( chain, tms );
}
int
chain_set_trst( chain_t *chain, int trst )
{
int old_trst = chain->cable->get_trst();
trst = chain->cable->set_trst( trst );
int old_trst = cable_get_trst( chain->cable );
trst = cable_set_trst( chain->cable, trst );
tap_state_set_trst( chain, old_trst, trst );
return trst;
}
@ -106,7 +97,7 @@ chain_set_trst( chain_t *chain, int trst )
int
chain_get_trst( chain_t *chain )
{
return chain->cable->get_trst();
return cable_get_trst( chain->cable );
}
void

@ -0,0 +1,72 @@
/*
* $Id$
*
* Copyright (C) 2003 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>, 2003.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "parport.h"
extern parport_driver_t direct_parport_driver;
parport_driver_t *parport_drivers[] = {
&direct_parport_driver,
NULL /* last must be NULL */
};
int
parport_open( parport_t *port )
{
return port->driver->open( port );
}
int
parport_close( parport_t *port )
{
return port->driver->close( port );
}
int
parport_set_data( parport_t *port, uint8_t data )
{
return port->driver->set_data( port, data );
}
int
parport_get_data( parport_t *port )
{
return port->driver->get_data( port );
}
int
parport_get_status( parport_t *port )
{
return port->driver->get_status( port );
}
int
parport_set_control( parport_t *port, uint8_t data )
{
return port->driver->set_control( port, data );
}

@ -0,0 +1,216 @@
/*
* $Id$
*
* Direct Parallel Port Connection Driver
* Copyright (C) 2003 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>, 2003.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "gettext.h"
#define _(s) gettext(s)
#define N_(s) gettext_noop(s)
#define P_(s,p,n) ngettext(s,p,n)
#include <stdlib.h>
#include <sys/io.h>
#include <string.h>
#include "parport.h"
#include "cable.h"
parport_driver_t direct_parport_driver;
typedef struct port_node_t port_node_t;
struct port_node_t {
parport_t *port;
port_node_t *next;
};
static port_node_t *ports = NULL; /* direct parallel ports */
typedef struct {
unsigned int port;
} direct_params_t;
static parport_t *
direct_parport_alloc( unsigned int port )
{
direct_params_t *params = malloc( sizeof *params );
parport_t *parport = malloc( sizeof *parport );
port_node_t *node = malloc( sizeof *node );
if (!node || !parport || !params) {
free( node );
free( parport );
free( params );
return NULL;
}
params->port = port;
parport->params = params;
parport->driver = &direct_parport_driver;
parport->cable = NULL;
node->port = parport;
node->next = ports;
ports = node;
return parport;
}
static void
direct_parport_free( parport_t *port )
{
port_node_t **prev;
for (prev = &ports; *prev; prev = &((*prev)->next))
if ((*prev)->port == port)
break;
if (*prev) {
port_node_t *pn = *prev;
*prev = pn->next;
free( pn );
}
free( port->params );
free( port );
}
static cable_t *
direct_connect( const char **par, int parnum )
{
int i;
unsigned int port;
port_node_t *pn;
parport_t *parport;
cable_t *cable;
if (parnum != 2) {
printf( _("Syntax error!\n") );
return NULL;
}
if ((sscanf( par[0], "0x%x", &port ) != 1) && (sscanf( par[0], "%d", &port ) != 1)) {
printf( _("Invalid port address!\n") );
return NULL;
}
for (pn = ports; pn; pn = pn->next) {
unsigned int aport;
aport = ((direct_params_t*) pn->port->params)->port;
if (abs( aport - port ) < 3) {
printf( _("Disconnecting %s from parallel port at 0x%x\n"), pn->port->cable->driver->description, aport );
pn->port->cable->driver->disconnect( pn->port->cable );
}
}
if (strcmp( par[1], "none" ) == 0) {
printf( _("Changed cable to 'none'\n") );
return NULL;
}
for (i = 0; cable_drivers[i]; i++)
if (strcmp( par[1], cable_drivers[i]->name ) == 0)
break;
if (!cable_drivers[i]) {
printf( _("Unknown cable: %s\n"), par[1] );
return NULL;
}
printf( _("Initializing %s on parallel port at 0x%x\n"), cable_drivers[i]->description, port );
parport = direct_parport_alloc( port );
if (!parport) {
printf( _("%s(%d) Out of memory.\n"), __FILE__, __LINE__ );
return NULL;
}
cable = cable_drivers[i]->connect( cable_drivers[i], parport );
if (!cable)
direct_parport_free( parport );
return cable;
}
static int
direct_open( parport_t *parport )
{
unsigned int port = ((direct_params_t *) parport->params)->port;
return ((port + 3 <= 0x400) && ioperm( port, 3, 1 )) || ((port + 3 > 0x400) && iopl( 3 ));
}
static int
direct_close( parport_t *parport )
{
unsigned int port = ((direct_params_t *) parport->params)->port;
return (port + 3 <= 0x400) ? ioperm( port, 3, 0 ) : iopl( 0 );
}
static int
direct_set_data( parport_t *parport, uint8_t data )
{
unsigned int port = ((direct_params_t *) parport->params)->port;
outb( data, port );
return 0;
}
static int
direct_get_data( parport_t *parport )
{
unsigned int port = ((direct_params_t *) parport->params)->port;
return inb( port );
}
static int
direct_get_status( parport_t *parport )
{
unsigned int port = ((direct_params_t *) parport->params)->port;
return inb( port + 1 ) ^ 0x80; /* BUSY is inverted */
}
static int
direct_set_control( parport_t *parport, uint8_t data )
{
unsigned int port = ((direct_params_t *) parport->params)->port;
outb( data, port + 2 );
return 0;
}
parport_driver_t direct_parport_driver = {
"parallel",
direct_connect,
direct_parport_free,
direct_open,
direct_close,
direct_set_data,
direct_get_data,
direct_get_status,
direct_set_control
};

@ -65,7 +65,7 @@ tap_shift_register( chain_t *chain, const tap_register *in, tap_register *out, i
chain_clock( chain, 0, 0 ); /* save last TDO bit :-) */
for (i = 0; i < in->len; i++) {
if (out && (i < out->len))
out->data[i] = chain->cable->get_tdo();
out->data[i] = cable_get_tdo( chain->cable );
chain_clock( chain, (exit && ((i + 1) == in->len)) ? 1 : 0, in->data[i] ); /* Shift (& Exit1) */
}
/* Shift-DR, Shift-IR, Exit1-DR or Exit1-IR state */

Loading…
Cancel
Save