diff --git a/jtag/ChangeLog b/jtag/ChangeLog index f71d5426..ffcad78f 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,21 @@ +2003-01-18 Marcel Telka + + * src/jtag.c (main): Added new 'frequency' command. + * src/help.c (help): Added help for 'frequency' command. + * include/cable.h (cable_wait): Added new function prototype. + * src/tap/cable.c (cable_wait): Added new function. + * src/tap/cable/byteblaster.c (byteblaster_clock): Added support for TCK + frequency limit. + (byteblaster_get_tdo): Ditto. + * src/tap/cable/dlc5.c (dlc5_clock): Ditto. + (dlc5_get_tdo): Ditto. + * src/tap/cable/ea253.c (ea253_clock): Ditto. + (ea253_get_tdo): Ditto. + * src/tap/cable/ei012.c (ei012_clock): Ditto. + (ei012_get_tdo): Ditto. + * src/tap/cable/wiggler.c (wiggler_clock): Ditto. + (wiggler_get_tdo): Ditto. + 2003-01-16 Marcel Telka * data/MANUFACTURERS: Added Cypress (patch 669157). Thanks to Chris Ellec. diff --git a/jtag/NEWS b/jtag/NEWS index b9b2acfe..5f3ab4f1 100644 --- a/jtag/NEWS +++ b/jtag/NEWS @@ -1,6 +1,7 @@ $Id$ * Added new manufacturer: Cypress. (patch 669157, Chris Ellec) + * Added new 'frequency' command to limit maximum TCK frequency jtag-0.2.1 (2003-01-13): diff --git a/jtag/include/cable.h b/jtag/include/cable.h index 805f9485..88e8bde3 100644 --- a/jtag/include/cable.h +++ b/jtag/include/cable.h @@ -38,6 +38,9 @@ typedef struct { void (*set_trst)( int ); } cable_driver_t; +extern uint32_t frequency; +void cable_wait( void ); + extern cable_driver_t *cable; #define tap_clock cable->clock #define tap_get_tdo cable->get_tdo diff --git a/jtag/src/help.c b/jtag/src/help.c index 24aa09fe..ebfcb6b3 100644 --- a/jtag/src/help.c +++ b/jtag/src/help.c @@ -40,6 +40,7 @@ help( const char *cmd ) "\n" "quit exit from %s\n" "help display this help\n" + "frequency setup JTAG frequency\n" "cable select JTAG cable\n" "detect detect parts on the JTAG chain\n" "discovery discovery unknown parts in the JTAG chain\n" @@ -64,6 +65,19 @@ help( const char *cmd ) "Usage: help [COMMAND]\n" "Print short help for COMMAND, or list of available commands.\n" ); + else if (strcmp( cmd, "frequency" ) == 0) + printf( + "Usage: frequency FREQ\n" + "Change TCK frequency to FREQ.\n" + "\n" + "FREQ is in hertz. It's a maximum TCK frequency for JTAG interface.\n" + "In some cases the TCK frequency is less than FREQ, but the frequency\n" + "is never more than FREQ. Maximum supported frequency depends on JTAG\n" + "adapter.\n" + "\n" + "FREQ must be an unsigned integer. Minimum allowed frequency is 1 Hz.\n" + "Use 0 for FREQ to disable frequency limit.\n" + ); else if (strcmp( cmd, "cable" ) == 0) { int i; diff --git a/jtag/src/jtag.c b/jtag/src/jtag.c index d5980ea7..551c5bba 100644 --- a/jtag/src/jtag.c +++ b/jtag/src/jtag.c @@ -100,6 +100,26 @@ main( void ) continue; } + if (strcmp( t, "frequency" ) == 0) { + uint32_t freq; + + t = get_token( NULL ); + if (!t) { + printf( "Missing argument(s)\n" ); + continue; + } + if ((sscanf( t, "0x%x", &freq ) != 1) && (sscanf( t, "%u", &freq ) != 1)) { + printf( "syntax error\n" ); + continue; + } + + printf( "Setting TCK frequency to %u Hz\n", freq ); + + frequency = freq; + + continue; + } + if (strcmp( t, "cable" ) == 0) { int i; unsigned int port; diff --git a/jtag/src/tap/cable.c b/jtag/src/tap/cable.c index c49236bd..9b96cf3a 100644 --- a/jtag/src/tap/cable.c +++ b/jtag/src/tap/cable.c @@ -23,6 +23,8 @@ */ #include +#include +#include #include "cable.h" @@ -32,6 +34,8 @@ extern cable_driver_t ea253_cable_driver; extern cable_driver_t ei012_cable_driver; extern cable_driver_t wiggler_cable_driver; +uint32_t frequency = 0; + cable_driver_t *cable_drivers[] = { &byteblaster_cable_driver, &dlc5_cable_driver, @@ -40,3 +44,18 @@ cable_driver_t *cable_drivers[] = { &wiggler_cable_driver, NULL /* last must be NULL */ }; + +void +cable_wait( void ) +{ + useconds_t s; + + if (!frequency) + return; + + s = 1000000 / frequency / 2; + if (s == 0) + s = 1; + + usleep( s ); +} diff --git a/jtag/src/tap/cable/byteblaster.c b/jtag/src/tap/cable/byteblaster.c index efa2eabe..a59f9294 100644 --- a/jtag/src/tap/cable/byteblaster.c +++ b/jtag/src/tap/cable/byteblaster.c @@ -77,7 +77,9 @@ byteblaster_clock( int tms, int tdi ) tdi &= 1; outb( (0 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); outb( (1 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); tap_state_clock( tms ); } @@ -86,6 +88,7 @@ static int byteblaster_get_tdo( void ) { outb( 0 << TCK, port ); + cable_wait(); return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */ } diff --git a/jtag/src/tap/cable/dlc5.c b/jtag/src/tap/cable/dlc5.c index 4e4c9249..5a5fb946 100644 --- a/jtag/src/tap/cable/dlc5.c +++ b/jtag/src/tap/cable/dlc5.c @@ -77,7 +77,9 @@ dlc5_clock( int tms, int tdi ) tdi &= 1; outb( (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); outb( (1 << PROG) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); tap_state_clock( tms ); } @@ -86,6 +88,7 @@ static int dlc5_get_tdo( void ) { outb( (1 << PROG) | (0 << TCK), port ); + cable_wait(); return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */ } diff --git a/jtag/src/tap/cable/ea253.c b/jtag/src/tap/cable/ea253.c index e20a20f1..28c3ac01 100644 --- a/jtag/src/tap/cable/ea253.c +++ b/jtag/src/tap/cable/ea253.c @@ -76,7 +76,9 @@ ea253_clock( int tms, int tdi ) tdi &= 1; outb( (trst << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); outb( (trst << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); tap_state_clock( tms ); } @@ -85,6 +87,7 @@ static int ea253_get_tdo( void ) { outb( (tap_state_get_trst() << TRST) | (0 << TCK), port ); + cable_wait(); return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */ } diff --git a/jtag/src/tap/cable/ei012.c b/jtag/src/tap/cable/ei012.c index 92728216..74474cad 100644 --- a/jtag/src/tap/cable/ei012.c +++ b/jtag/src/tap/cable/ei012.c @@ -77,7 +77,9 @@ ei012_clock( int tms, int tdi ) tdi &= 1; outb( (trst << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); outb( (trst << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); tap_state_clock( tms ); } @@ -86,6 +88,7 @@ static int ei012_get_tdo( void ) { outb( (tap_state_get_trst() << TRST) | (0 << TCK), port ); + cable_wait(); return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */ } diff --git a/jtag/src/tap/cable/wiggler.c b/jtag/src/tap/cable/wiggler.c index 3987d0cf..1b9b6aa6 100644 --- a/jtag/src/tap/cable/wiggler.c +++ b/jtag/src/tap/cable/wiggler.c @@ -80,7 +80,9 @@ wiggler_clock( int tms, int tdi ) tdi &= 1; outb( (trst << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); outb( (trst << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI), port ); + cable_wait(); tap_state_clock( tms ); } @@ -89,6 +91,7 @@ static int wiggler_get_tdo( void ) { outb( (tap_state_get_trst() << TRST) | (0 << TCK), port ); + cable_wait(); return ((inb( port + 1 ) ^ 0x80) >> TDO) & 1; /* BUSY is inverted */ }