diff --git a/jtag/ChangeLog b/jtag/ChangeLog index c0153a13..a3e80f98 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,5 +1,11 @@ 2008-10-26 Arnim Laeuger + * configure.ac, doc/UrJTAG.txt, src/tap/Makefile.am, + src/tap/cable/ts7800.c, src/tap/cable.c, THANKS: + [ 2187342 ] Technologic Systems TS-7800 JTAG support + (Catalin Ionescu, Stanislav Sinyagin) + cable driver only + * src/cmd/print.c, doc/UrJTAG.txt: [ 1964834 ] Add 'print instruction' support to print command (Hartley Sweeten) diff --git a/jtag/THANKS b/jtag/THANKS index c46a789f..04ebe6ef 100644 --- a/jtag/THANKS +++ b/jtag/THANKS @@ -32,6 +32,7 @@ Jachym Holecek August Hörandl Rojhalat Ibrahim Andrey F. Ilchuk +Catalin Ionescu Gabor Juhos Wojtek Kaniewski Stas Khirman diff --git a/jtag/configure.ac b/jtag/configure.ac index d62ef186..d62b9852 100644 --- a/jtag/configure.ac +++ b/jtag/configure.ac @@ -446,7 +446,7 @@ CHECK_DRIVER([$busdrivers], [enabled_bus_drivers], [zefant_xs3], [ENABLE_BUS_ # Enable cable drivers AC_DEFUN([DEF_ENABLE_CABLEDRIVERS], [\ arcom byteblaster dlc5 ea253 ei012 ft2232 igloo jlink keithkoep lattice mpcbdm triton usbblaster wiggler xpc]) -AC_DEFUN([DEF_DISABLE_CABLEDRIVERS], [ep9307 jim]) +AC_DEFUN([DEF_DISABLE_CABLEDRIVERS], [ep9307 jim ts7800]) AC_ARG_ENABLE(cable, [AS_HELP_STRING([--enable-cable], [Enable default set or specific cable drivers.])] [AS_HELP_STRING([], ['default' enables:])] @@ -488,6 +488,7 @@ CHECK_DRIVER([$cabledrivers], [enabled_cable_drivers], [triton], [ENABLE_CA CHECK_DRIVER([$cabledrivers], [enabled_cable_drivers], [usbblaster], [ENABLE_CABLE_USBBLASTER]) CHECK_DRIVER([$cabledrivers], [enabled_cable_drivers], [wiggler], [ENABLE_CABLE_WIGGLER]) CHECK_DRIVER([$cabledrivers], [enabled_cable_drivers], [xpc], [ENABLE_CABLE_XPC]) +CHECK_DRIVER([$cabledrivers], [enabled_cable_drivers], [ts7800], [ENABLE_CABLE_TS7800]) # Enable lowlevel drivers diff --git a/jtag/doc/UrJTAG.txt b/jtag/doc/UrJTAG.txt index 3e1f7797..2b2c624b 100644 --- a/jtag/doc/UrJTAG.txt +++ b/jtag/doc/UrJTAG.txt @@ -233,6 +233,9 @@ Other USB cables: * Segger/IAR J-Link / Atmel SAM-ICE (experimental, work in progress) * Xilinx Platform USB Cable / DLC9 (slow, experimental, work in progress - don't use) +Other cables: + * Technologic Systems TS-7800 SoC GPIO builtin JTAG interface + ==== JTAG-aware parts (chips) ==== The data/ directory of the UrJTAG installation has some more, but at diff --git a/jtag/src/tap/Makefile.am b/jtag/src/tap/Makefile.am index 8cea4d1c..2b4da0b2 100644 --- a/jtag/src/tap/Makefile.am +++ b/jtag/src/tap/Makefile.am @@ -116,6 +116,11 @@ libtap_a_SOURCES += \ cable/ft2232.c endif +if ENABLE_CABLE_TS7800 +libtap_a_SOURCES += \ + cable/ts7800.c +endif + if HAVE_LIBUSB libtap_a_SOURCES += \ diff --git a/jtag/src/tap/cable.c b/jtag/src/tap/cable.c index c458864c..a1cd863c 100644 --- a/jtag/src/tap/cable.c +++ b/jtag/src/tap/cable.c @@ -66,6 +66,7 @@ extern cable_driver_t xpc_int_cable_driver; extern cable_driver_t xpc_ext_cable_driver; extern cable_driver_t jlink_cable_driver; extern cable_driver_t ep9307_cable_driver; +extern cable_driver_t ts7800_cable_driver; cable_driver_t *cable_drivers[] = { #ifdef ENABLE_CABLE_ARCOM @@ -134,6 +135,10 @@ cable_driver_t *cable_drivers[] = { #ifdef ENABLE_CABLE_EP9307 &ep9307_cable_driver, #endif + +#ifdef ENABLE_CABLE_TS7800 + &ts7800_cable_driver, +#endif NULL /* last must be NULL */ }; diff --git a/jtag/src/tap/cable/ts7800.c b/jtag/src/tap/cable/ts7800.c new file mode 100644 index 00000000..090f2dd7 --- /dev/null +++ b/jtag/src/tap/cable/ts7800.c @@ -0,0 +1,273 @@ +/* + * $Id$ + * + * Technologic Systems TS-7800 SoC GPIO JTAG Cable Driver + * Copyright (C) 2008 Catalin Ionescu + * Based on Vision EP9307 SoM GPIO JTAG Cable Driver + * Copyright (C) 2007, 2008 H Hartley Sweeten + * + * 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 Catalin Ionescu , 2008 + * + */ + +#include "sysdep.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "cable.h" +#include "chain.h" + +#include "generic.h" + +#include + +#define GPIO_BASE 0xF1010000 +#define GPIO_OUT (0x0100/4) +#define GPIO_DIR (0x0104/4) +#define GPIO_INPOL (0x010C/4) +#define GPIO_IN (0x0110/4) +#define GPIO_INTEDGE (0x0118/4) +#define GPIO_INTLEV (0x011C/4) + +#define TDO 4 +#define TDI 2 +#define TMS 5 +#define TCK 1 + +#define HGPIO(b) (1 << (b)) +#define ts7800_TDO HGPIO(TDO) +#define ts7800_TDI HGPIO(TDI) +#define ts7800_TMS HGPIO(TMS) +#define ts7800_TCK HGPIO(TCK) + +#define GPIO_INPUT_MASK ((ts7800_TCK)|(ts7800_TMS)|(ts7800_TDI)) +#define GPIO_OUTPUT_MASK ts7800_TDO +#define GPIO_BITMASK (~((ts7800_TDO)|(ts7800_TDI)|(ts7800_TMS)|(ts7800_TCK))) + +typedef struct { + int fd_dev_mem; + void *map_base; + size_t map_size; + uint32_t *gpio_base; + int trst; + uint32_t lastout; +} ts7800_params_t; + +static int +ts7800_gpio_open( cable_t *cable ) +{ + ts7800_params_t *p = cable->params; + off_t map_mask; + + /* Open the memory device so we can access the hardware registers */ + p->fd_dev_mem = open("/dev/mem", O_RDWR | O_SYNC); + if (p->fd_dev_mem == -1) { + printf( _("Error: unable to open /dev/mem\n") ); + return -1; + } + + p->map_size = getpagesize(); + map_mask = p->map_size - 1; + + /* Map the GPIO registers */ + p->map_base = mmap(0, p->map_size, PROT_READ | PROT_WRITE, MAP_SHARED, p->fd_dev_mem, GPIO_BASE & ~map_mask); + if (p->map_base == MAP_FAILED) { + printf( _("Error: unable to mmap the GPIO registers\n") ); + close (p->fd_dev_mem); + return -1; + } + + /* Create the pointers to access the GPIO registers */ + p->gpio_base = (uint32_t*)p->map_base; + + /* Set the GPIO pins as inputs/outputs as needed for the JTAG interface */ + p->gpio_base[GPIO_DIR] = ( p->gpio_base[GPIO_DIR] & GPIO_BITMASK ) | GPIO_OUTPUT_MASK; + + p->lastout=p->gpio_base[GPIO_OUT]; + + return 0; +} + +static int +ts7800_gpio_close( cable_t *cable ) +{ + ts7800_params_t *p = cable->params; + + /* Unmap the GPIO registers */ + if (munmap(p->map_base, p->map_size) == -1) { + printf( _("Error: unable to munmap the GPIO registers\n")); + } + close(p->fd_dev_mem); + return 0; +} + +static int +ts7800_gpio_write( cable_t *cable, uint8_t data ) +{ + ts7800_params_t *p = cable->params; + + p->gpio_base[GPIO_OUT] = p->lastout = (p->lastout & GPIO_BITMASK) | data; + cable_wait(cable); + + return 0; +} + +static int +ts7800_gpio_read( cable_t *cable ) +{ + ts7800_params_t *p = cable->params; + + return p->gpio_base[GPIO_IN]; +} + +static int +ts7800_connect( char *params[], cable_t *cable ) +{ + ts7800_params_t *cable_params; + + if ( cmd_params( params ) != 1) { + printf( _("Error: This cable type does not accept parameters!\n") ); + return 1; + } + + printf( _("Initializing TS-7800 Built-in JTAG Chain\n") ); + + cable_params = malloc( sizeof *cable_params ); + if (!cable_params) { + printf( _("%s(%d) Out of memory\n"), __FILE__, __LINE__ ); + free( cable ); + return 4; + } + + cable->params = cable_params; + cable->chain = NULL; + cable->delay = 1000; + + return 0; +} + +static void +ts7800_disconnect( cable_t *cable ) +{ + ts7800_gpio_close( cable ); + chain_disconnect( cable->chain ); +} + +static void +ts7800_cable_free( cable_t *cable ) +{ + free( cable->params ); + free( cable ); +} + +static int +ts7800_init( cable_t *cable ) +{ + ts7800_params_t *p = cable->params; + + if (ts7800_gpio_open( cable )) + return -1; + + p->trst = 1; + + return 0; +} + +static void +ts7800_done( cable_t *cable ) +{ + ts7800_gpio_close( cable ); +} + +static void +ts7800_clock( cable_t *cable, int tms, int tdi, int n ) +{ + int bit_mask; + int i; + + tms = tms ? 1 : 0; + tdi = tdi ? 1 : 0; + + bit_mask = (tms << TMS) | (tdi << TDI); + + for (i = 0; i < n; i++) { + ts7800_gpio_write( cable, (0 << TCK) | bit_mask ); + ts7800_gpio_write( cable, (1 << TCK) | bit_mask ); + ts7800_gpio_write( cable, (0 << TCK) | bit_mask ); + } +} + +/** + * NOTE: This also lowers the TDI and TMS lines; is this intended? + */ +static int +ts7800_get_tdo( cable_t *cable ) +{ + ts7800_gpio_write( cable, ((ts7800_params_t *)cable->params)->lastout & ~(0 << TCK) ); + return (ts7800_gpio_read( cable ) >> TDO) & 1; +} + +static int +ts7800_set_trst( cable_t *cable, int trst ) +{ + ts7800_params_t *p = cable->params; + + p->trst = trst ? 1 : 0; + + return p->trst; +} + +static int +ts7800_get_trst( cable_t *cable ) +{ + return ((ts7800_params_t *)cable->params)->trst; +} + +static void +ts7800_help( const char *cablename ) +{ + printf( _( + "Usage: cable %s\n" + "\n" + ), cablename ); +} + +cable_driver_t ts7800_cable_driver = { + "ts7800", + N_("TS-7800 Built-in JTAG Chain"), + ts7800_connect, + ts7800_disconnect, + ts7800_cable_free, + ts7800_init, + ts7800_done, + generic_set_frequency, + ts7800_clock, + ts7800_get_tdo, + generic_transfer, + ts7800_set_trst, + ts7800_get_trst, + generic_flush_one_by_one, + ts7800_help +};