diff --git a/jtag/ChangeLog b/jtag/ChangeLog index d77cf179..32477429 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,8 +1,34 @@ +2008-02-24 Kolja Waschk + + * include/cable.h, include/usbconn.h, include/usbconn/libusb.h, + src/tap/cable.c, src/tap/usbconn/libusb.c, src/tap/parport.c, + src/tap/usbconn.c, src/tap/Makefile.am: Merged code from usb_abstraction + branch, adding a "usbconn" link driver (similar to the existing + parport link driver) for USB cables. + + * src/tap/cable/generic_parport.c, src/tap/cable/generic_parport.h, + src/tap/cable/generic_usbconn.h, src/tap/cable/generic_usbconn.c, + src/tap/cable/generic.c, src/tap/cable/generic.h: Separated link-specific + code from generic.c into addition source files for parport and usbconn + + * src/tap/cable/wiggler.c, src/tap/cable/arcom.c, src/tap/cable/mpcbdm.c, + src/tap/cable/usbblaster.c, src/tap/cable/jlink.c, src/tap/cable/ea253.c, + src/tap/cable/vision_ep9307.c, src/tap/cable/triton.c, src/tap/cable/ei012.c, + src/tap/cable/byteblaster.c, src/tap/cable/wiggler2.c, src/tap/cable/dlc5.c, + src/tap/cable/ft2232.c, src/tap/cable/keithkoep.c, src/tap/cable/lattice.c: + Small modifications to adapt to the changes in cable.h and generic.h + + * src/tap/cable/xpc.c, src/tap/parport/xpcu_pp.c, src/tap/parport/xpcu_common.c: + Xilinx Platform Cable USB driver now based on usbconn link driver + + * src/tap/cable/jlink.c: New driver for Segger J-Link, Atmel SAM-ICE etc. + based on usbconn link driver + 2008-02-24 Eugene Boldenkov * src/bus/mpc824x.c: Add 32-bit bus support (1900847) -2008-02-24 Mike Frysinger +2008-02-24 Mike Frysinger * configure.ac: Fix building out of tree (1899908), only use libusb flags as needed (1899930), provide flag about wchar.h presence (1899922) diff --git a/jtag/include/cable.h b/jtag/include/cable.h index 923dec0e..29c66d8e 100644 --- a/jtag/include/cable.h +++ b/jtag/include/cable.h @@ -30,6 +30,7 @@ typedef struct cable_t cable_t; +#include "usbconn.h" #include "parport.h" #include "chain.h" @@ -107,7 +108,10 @@ struct cable_queue_info_t { struct cable_t { cable_driver_t *driver; - parport_t *port; + union { + usbconn_t *usb; + parport_t *port; + } link; void *params; chain_t *chain; cable_queue_info_t todo; diff --git a/jtag/include/usbconn.h b/jtag/include/usbconn.h new file mode 100644 index 00000000..c733f06d --- /dev/null +++ b/jtag/include/usbconn.h @@ -0,0 +1,64 @@ +/* + * $Id: usbconn.h 809 2007-12-04 07:06:49Z kawk $ + * + * USB Device Connection Driver Interface + * Copyright (C) 2008 K. Waschk + * + * 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 Kolja Waschk , 2008 + * + */ + +#ifndef USBCONN_H +#define USBCONN_H + +#include + +typedef struct usbconn_t usbconn_t; + +#include "cable.h" + +typedef struct +{ + char *name; + char *desc; + char *driver; + int32_t vid; + int32_t pid; +} usbconn_cable_t; + +typedef struct { + const char *type; + usbconn_t *(*connect)( const char **, int, usbconn_cable_t *); + void (*free)( usbconn_t * ); + int (*open)( usbconn_t * ); + int (*close)( usbconn_t * ); +} usbconn_driver_t; + +struct usbconn_t { + usbconn_driver_t *driver; + void *params; + cable_t *cable; +}; + +usbconn_t *usbconn_connect( const char **, int, usbconn_cable_t *); +int usbconn_free( usbconn_t *conn ); +int usbconn_open( usbconn_t *conn ); +int usbconn_close( usbconn_t *conn ); +extern usbconn_driver_t *usbconn_drivers[]; + +#endif /* USBCONN_H */ diff --git a/jtag/include/usbconn/libusb.h b/jtag/include/usbconn/libusb.h new file mode 100644 index 00000000..be2c87ba --- /dev/null +++ b/jtag/include/usbconn/libusb.h @@ -0,0 +1,38 @@ +/* + * $Id: usbconn/libusb.h,v 1.7 2003/08/19 09:05:25 telka Exp $ + * + * Link driver for accessing USB devices via libusb + * + * Copyright (C) 2008 K. Waschk + * + * 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 Kolja Waschk, 2008 + * + */ + +#ifndef _USBCONN_LIBUSB_H +#define _USBCONN_LIBUSB_H 1 + +#include + +typedef struct { + struct usb_device *dev; + struct usb_dev_handle *handle; +} libusb_param_t; + +#endif + diff --git a/jtag/src/tap/Makefile.am b/jtag/src/tap/Makefile.am index d1d1d0f2..d92c52e0 100644 --- a/jtag/src/tap/Makefile.am +++ b/jtag/src/tap/Makefile.am @@ -34,9 +34,14 @@ libtap_a_SOURCES = \ parport/direct.c \ parport/ppdev.c \ parport/ppi.c \ + usbconn.c \ cable.c \ cable/generic.h \ cable/generic.c \ + cable/generic_usbconn.h \ + cable/generic_usbconn.c \ + cable/generic_parport.h \ + cable/generic_parport.c \ cable/arcom.c \ cable/byteblaster.c \ cable/dlc5.c \ @@ -51,9 +56,9 @@ libtap_a_SOURCES = \ if HAVE_LIBUSB libtap_a_SOURCES += \ - parport/xpcu_common.c \ - parport/xpcu_pp.c \ - cable/xpc.c + cable/xpc.c \ + cable/jlink.c \ + usbconn/libusb.c endif if ENABLE_JIM diff --git a/jtag/src/tap/cable.c b/jtag/src/tap/cable.c index 57ad9ae2..6f08dac4 100644 --- a/jtag/src/tap/cable.c +++ b/jtag/src/tap/cable.c @@ -68,6 +68,7 @@ extern cable_driver_t wiggler_cable_driver; #ifdef HAVE_LIBUSB extern cable_driver_t xpc_int_cable_driver; extern cable_driver_t xpc_ext_cable_driver; +extern cable_driver_t jlink_cable_driver; #endif #ifdef ENABLE_EP9307 extern cable_driver_t ep9307_cable_driver; @@ -102,6 +103,7 @@ cable_driver_t *cable_drivers[] = { #ifdef HAVE_LIBUSB &xpc_int_cable_driver, &xpc_ext_cable_driver, + &jlink_cable_driver, #endif #ifdef ENABLE_EP9307 &ep9307_cable_driver, diff --git a/jtag/src/tap/cable/arcom.c b/jtag/src/tap/cable/arcom.c index aaec0cb4..e7e174fe 100644 --- a/jtag/src/tap/cable/arcom.c +++ b/jtag/src/tap/cable/arcom.c @@ -30,6 +30,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" /* * data D[7:0] (pins 9:2) @@ -53,11 +54,11 @@ arcom_init( cable_t *cable ) { int data; - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; - if ((data = parport_get_data( cable->port )) < 0) { - if (parport_set_data( cable->port, 1 << TRST )) + if ((data = parport_get_data( cable->link.port )) < 0) { + if (parport_set_data( cable->link.port, 1 << TRST )) return -1; PARAM_TRST(cable) = 1; } else @@ -75,9 +76,9 @@ arcom_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); } } @@ -85,9 +86,9 @@ arcom_clock( cable_t *cable, int tms, int tdi, int n ) static int arcom_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (0 << TCK) ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int @@ -95,18 +96,18 @@ arcom_set_trst( cable_t *cable, int trst ) { PARAM_TRST(cable) = trst ? 1 : 0; - parport_set_data( cable->port, PARAM_TRST(cable) << TRST ); + parport_set_data( cable->link.port, PARAM_TRST(cable) << TRST ); return PARAM_TRST(cable); } cable_driver_t arcom_cable_driver = { "ARCOM", N_("Arcom JTAG Cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, arcom_init, - generic_done, + generic_parport_done, generic_set_frequency, arcom_clock, arcom_get_tdo, @@ -114,5 +115,5 @@ cable_driver_t arcom_cable_driver = { arcom_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/byteblaster.c b/jtag/src/tap/cable/byteblaster.c index d317eeec..2254204f 100644 --- a/jtag/src/tap/cable/byteblaster.c +++ b/jtag/src/tap/cable/byteblaster.c @@ -38,6 +38,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" /* * data D[7:0] (pins 9:2) @@ -71,26 +72,26 @@ byteblaster_init( cable_t *cable ) { int BB_II = 0; - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; PARAM_TRST(cable) = 1; /* check if a ByteBlaster or ByteBlasterMV is connected */ - parport_set_data( cable->port, 1 << BB_CHECK); - if ( !( ( parport_get_status( cable->port ) >> BB_PRESENT ) & 1 ) ) + parport_set_data( cable->link.port, 1 << BB_CHECK); + if ( !( ( parport_get_status( cable->link.port ) >> BB_PRESENT ) & 1 ) ) BB_II = 1; - parport_set_data( cable->port, 0); - if ( ( parport_get_status( cable->port ) >> BB_PRESENT ) & 1 ) + parport_set_data( cable->link.port, 0); + if ( ( parport_get_status( cable->link.port ) >> BB_PRESENT ) & 1 ) BB_II = 1; /* check if the power supply is ok (only for ByteBlaster II) */ /* if no ByteBlaster at all is connected this check will fail, too */ - if ( ( BB_II ) && ( ( parport_get_status( cable->port ) >> VCC_OK_N ) & 1 ) ) + if ( ( BB_II ) && ( ( parport_get_status( cable->link.port ) >> VCC_OK_N ) & 1 ) ) return -1; /* Enable ByteBlaster */ - parport_set_control( cable->port, BB_ENABLE ); + parport_set_control( cable->link.port, BB_ENABLE ); return 0; } @@ -104,9 +105,9 @@ byteblaster_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (0 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); - parport_set_data( cable->port, (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (1 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); } } @@ -114,9 +115,9 @@ byteblaster_clock( cable_t *cable, int tms, int tdi, int n ) static int byteblaster_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, 0 << TCK ); + parport_set_data( cable->link.port, 0 << TCK ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int @@ -128,11 +129,11 @@ byteblaster_set_trst( cable_t *cable, int trst ) cable_driver_t byteblaster_cable_driver = { "ByteBlaster", N_("Altera ByteBlaster/ByteBlaster II/ByteBlasterMV Parallel Port Download Cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, byteblaster_init, - generic_done, + generic_parport_done, generic_set_frequency, byteblaster_clock, byteblaster_get_tdo, @@ -140,5 +141,5 @@ cable_driver_t byteblaster_cable_driver = { byteblaster_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/dlc5.c b/jtag/src/tap/cable/dlc5.c index 727dcc79..de7469cd 100644 --- a/jtag/src/tap/cable/dlc5.c +++ b/jtag/src/tap/cable/dlc5.c @@ -34,6 +34,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" /* see Figure B-1 in [1] */ @@ -58,7 +59,7 @@ static int dlc5_init( cable_t *cable ) { - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; PARAM_TRST(cable) = 1; @@ -75,9 +76,9 @@ dlc5_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); - parport_set_data( cable->port, (1 << PROG) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (1 << PROG) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); } } @@ -85,9 +86,9 @@ dlc5_clock( cable_t *cable, int tms, int tdi, int n ) static int dlc5_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, (1 << PROG) | (0 << TCK) ); + parport_set_data( cable->link.port, (1 << PROG) | (0 << TCK) ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int @@ -99,11 +100,11 @@ dlc5_set_trst( cable_t *cable, int trst ) cable_driver_t dlc5_cable_driver = { "DLC5", N_("Xilinx DLC5 JTAG Parallel Cable III"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, dlc5_init, - generic_done, + generic_parport_done, generic_set_frequency, dlc5_clock, dlc5_get_tdo, @@ -111,5 +112,5 @@ cable_driver_t dlc5_cable_driver = { dlc5_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/ea253.c b/jtag/src/tap/cable/ea253.c index e15928b2..9ac34167 100644 --- a/jtag/src/tap/cable/ea253.c +++ b/jtag/src/tap/cable/ea253.c @@ -30,6 +30,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" /* * data D[7:0] (pins 9:2) @@ -53,11 +54,11 @@ ea253_init( cable_t *cable ) { int data; - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; - if ((data = parport_get_data( cable->port )) < 0) { - if (parport_set_data( cable->port, 1 << TRST )) + if ((data = parport_get_data( cable->link.port )) < 0) { + if (parport_set_data( cable->link.port, 1 << TRST )) return -1; PARAM_TRST(cable) = 1; } else @@ -75,9 +76,9 @@ ea253_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); } } @@ -85,9 +86,9 @@ ea253_clock( cable_t *cable, int tms, int tdi, int n ) static int ea253_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (0 << TCK) ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int @@ -95,18 +96,18 @@ ea253_set_trst( cable_t *cable, int trst ) { PARAM_TRST(cable) = trst ? 1 : 0; - parport_set_data( cable->port, PARAM_TRST(cable) << TRST ); + parport_set_data( cable->link.port, PARAM_TRST(cable) << TRST ); return PARAM_TRST(cable); } cable_driver_t ea253_cable_driver = { "EA253", N_("ETC EA253 JTAG Cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, ea253_init, - generic_done, + generic_parport_done, generic_set_frequency, ea253_clock, ea253_get_tdo, @@ -114,5 +115,5 @@ cable_driver_t ea253_cable_driver = { ea253_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/ei012.c b/jtag/src/tap/cable/ei012.c index b8bc8cc0..2d8e63f6 100644 --- a/jtag/src/tap/cable/ei012.c +++ b/jtag/src/tap/cable/ei012.c @@ -30,6 +30,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" /* * data D[7:0] (pins 9:2) @@ -55,11 +56,11 @@ ei012_init( cable_t *cable ) { int data; - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; - if ((data = parport_get_data( cable->port )) < 0) { - if (parport_set_data( cable->port, 1 << TRST )) + if ((data = parport_get_data( cable->link.port )) < 0) { + if (parport_set_data( cable->link.port, 1 << TRST )) return -1; PARAM_TRST(cable) = 1; } else @@ -77,9 +78,9 @@ ei012_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); } } @@ -87,9 +88,9 @@ ei012_clock( cable_t *cable, int tms, int tdi, int n ) static int ei012_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (0 << TCK) ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int @@ -97,18 +98,18 @@ ei012_set_trst( cable_t *cable, int trst ) { PARAM_TRST(cable) = trst ? 1 : 0; - parport_set_data( cable->port, PARAM_TRST(cable) << TRST ); + parport_set_data( cable->link.port, PARAM_TRST(cable) << TRST ); return PARAM_TRST(cable); } cable_driver_t ei012_cable_driver = { "EI012", N_("ETC EI012 JTAG Cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, ei012_init, - generic_done, + generic_parport_done, generic_set_frequency, ei012_clock, ei012_get_tdo, @@ -116,5 +117,5 @@ cable_driver_t ei012_cable_driver = { ei012_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/ft2232.c b/jtag/src/tap/cable/ft2232.c index 56fb65af..5775ad65 100644 --- a/jtag/src/tap/cable/ft2232.c +++ b/jtag/src/tap/cable/ft2232.c @@ -36,7 +36,6 @@ #include "generic.h" - /* Maximum chunk to write to parport driver. Larger values might speed up comm, but there's an upper limit when too many bytes are sent and the underlying libftdi or libftd2xx @@ -214,7 +213,7 @@ push_to_send( params_t *params, uint8_t d ) static void send_and_receive( cable_t *cable, cable_flush_amount_t how_much ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; uint32_t bytes_sent, bytes_to_recv, bytes_recvd; uint16_t *send_idx; @@ -336,7 +335,7 @@ ft2232_set_frequency( cable_t *cable, uint32_t new_frequency ) static int ft2232_generic_init( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; if (parport_open( p )) @@ -374,7 +373,7 @@ ft2232_generic_init( cable_t *cable ) static int ft2232_jtagkey_init( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; if (parport_open( p )) @@ -423,7 +422,7 @@ ft2232_jtagkey_init( cable_t *cable ) static int ft2232_armusbocd_init( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; if (parport_open( p )) @@ -476,7 +475,7 @@ ft2232_armusbocd_init( cable_t *cable ) static int ft2232_oocdlinks_init( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; if (parport_open( p )) @@ -525,7 +524,7 @@ ft2232_oocdlinks_init( cable_t *cable ) static int ft2232_turtelizer2_init( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; if (parport_open( p )) @@ -569,7 +568,7 @@ ft2232_turtelizer2_init( cable_t *cable ) static int ft2232_usbtojtagif_init( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; if (parport_open( p )) @@ -614,7 +613,7 @@ ft2232_usbtojtagif_init( cable_t *cable ) static int ft2232_signalyzer_init( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; if (parport_open( p )) @@ -654,7 +653,7 @@ ft2232_signalyzer_init( cable_t *cable ) static void ft2232_generic_done( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; /* Set Data Bits Low Byte @@ -677,7 +676,7 @@ ft2232_generic_done( cable_t *cable ) static void ft2232_jtagkey_done( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; /* Set Data Bits Low Byte @@ -715,7 +714,7 @@ ft2232_jtagkey_done( cable_t *cable ) static void ft2232_armusbocd_done( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; /* Set Data Bits Low Byte @@ -754,7 +753,7 @@ ft2232_armusbocd_done( cable_t *cable ) static void ft2232_oocdlinks_done( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; /* Set Data Bits Low Byte @@ -786,7 +785,7 @@ ft2232_oocdlinks_done( cable_t *cable ) static void ft2232_turtelizer2_done( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; /* Set Data Bits Low Byte @@ -821,7 +820,7 @@ ft2232_turtelizer2_done( cable_t *cable ) static void ft2232_usbtojtagif_done( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; /* Set Data Bits Low Byte @@ -850,7 +849,7 @@ ft2232_usbtojtagif_done( cable_t *cable ) static void ft2232_signalyzer_done( cable_t *cable ) { - parport_t *p = cable->port; + parport_t *p = cable->link.port; params_t *params = (params_t *)cable->params; /* Set Data Bits Low Byte @@ -1320,7 +1319,7 @@ ft2232_connect( char *params[], cable_t *cable ) cable_params->recv_buffer = (uint8_t *)malloc( cable_params->recv_buffer_len ); cable_params->maxrecv = maxrecv; - cable->port = port; + cable->link.port = port; cable->params = cable_params; cable->chain = NULL; @@ -1333,7 +1332,7 @@ ft2232_cable_free( cable_t *cable ) { params_t *params = (params_t *)cable->params; - cable->port->driver->parport_free( cable->port ); + cable->link.port->driver->parport_free( cable->link.port ); free( params->send_buffer ); free( params->recv_buffer ); free( cable->params ); diff --git a/jtag/src/tap/cable/generic.c b/jtag/src/tap/cable/generic.c index 0f8e4144..092d2fe7 100644 --- a/jtag/src/tap/cable/generic.c +++ b/jtag/src/tap/cable/generic.c @@ -50,49 +50,6 @@ print_vector(int len, char *vec) } #endif -int -generic_connect( char *params[], cable_t *cable ) -{ - generic_params_t *cable_params = malloc( sizeof *cable_params ); - parport_t *port; - int i; - - if ( cmd_params( params ) < 3 ) { - printf( _("not enough arguments!\n") ); - return 1; - } - - /* search parport driver list */ - for (i = 0; parport_drivers[i]; i++) - if (strcasecmp( params[1], parport_drivers[i]->type ) == 0) - break; - if (!parport_drivers[i]) { - printf( _("Unknown port driver: %s\n"), params[1] ); - return 2; - } - - /* set up parport driver */ - port = parport_drivers[i]->connect( (const char **) ¶ms[2], - cmd_params( params ) - 2 ); - - if (port == NULL) { - printf( _("Error: Cable connection failed!\n") ); - return 3; - } - - if (!cable_params) { - free( cable_params ); - free( cable ); - return 4; - } - - cable->port = port; - cable->params = cable_params; - cable->chain = NULL; - - return 0; -} - void generic_disconnect( cable_t *cable ) { @@ -100,20 +57,6 @@ generic_disconnect( cable_t *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_transfer( cable_t *cable, int len, char *in, char *out ) { @@ -469,34 +412,3 @@ generic_set_frequency( cable_t *cable, uint32_t new_frequency ) } } -void -generic_lptcable_help( const char *cablename ) -{ - printf( _( - "Usage: cable %s parallel PORTADDR\n" -#if HAVE_LINUX_PPDEV_H - " or: cable %s ppdev PPDEV\n" -#endif -#if HAVE_DEV_PPBUS_PPI_H - " or: cable %s ppi PPIDEV\n" -#endif - "\n" - "PORTADDR parallel port address (e.g. 0x378)\n" -#if HAVE_LINUX_PPDEV_H - "PPDEF ppdev device (e.g. /dev/parport0)\n" -#endif -#if HAVE_DEV_PPBUS_PPI_H - "PPIDEF ppi device (e.g. /dev/ppi0)\n" -#endif - "\n" - ), -#if HAVE_LINUX_PPDEV_H - cablename, -#endif -#if HAVE_DEV_PPBUS_PPI_H - cablename, -#endif - cablename - ); -} - diff --git a/jtag/src/tap/cable/generic.h b/jtag/src/tap/cable/generic.h index 1d549e7b..b56811cf 100644 --- a/jtag/src/tap/cable/generic.h +++ b/jtag/src/tap/cable/generic.h @@ -36,15 +36,11 @@ typedef struct { #define PARAM_TRST(cable) ((generic_params_t *) cable->params)->trst #define PARAM_SRESET(cable) ((generic_params_t *) cable->params)->sreset -int generic_connect( char *params[], cable_t *cable ); void generic_disconnect( cable_t *cable ); -void generic_cable_free( cable_t *cable ); -void generic_done( cable_t *cable ); void generic_set_frequency( cable_t *cable, uint32_t new_freq ); int generic_transfer( cable_t *cable, int len, char *in, char *out ); int generic_get_trst( cable_t *cable ); void generic_flush_one_by_one( cable_t *cable, cable_flush_amount_t hm ); void generic_flush_using_transfer( cable_t *cable, cable_flush_amount_t hm ); -void generic_lptcable_help( const char *name ); #endif /* GENERIC_H */ diff --git a/jtag/src/tap/cable/generic_parport.c b/jtag/src/tap/cable/generic_parport.c new file mode 100644 index 00000000..6fc30bab --- /dev/null +++ b/jtag/src/tap/cable/generic_parport.c @@ -0,0 +1,137 @@ +/* + * $Id: generic.c 1003 2008-02-10 10:00:30Z kawk $ + * + * 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 , 2003. + * + */ + +#include "sysdep.h" + +#include +#include +#include + +#include "cable.h" +#include "chain.h" +#include "parport.h" +#include "generic.h" +#include "generic_parport.h" + +#include + +#undef VERBOSE + +#ifdef VERBOSE +void +print_vector(int len, char *vec) +{ + int i; + for(i=0;itype ) == 0) + break; + if (!parport_drivers[i]) { + printf( _("Unknown port driver: %s\n"), params[1] ); + return 2; + } + + /* set up parport driver */ + port = parport_drivers[i]->connect( (const char **) ¶ms[2], + cmd_params( params ) - 2 ); + + if (port == NULL) { + printf( _("Error: Cable connection failed!\n") ); + return 3; + } + + if (!cable_params) { + free( cable_params ); + free( cable ); + return 4; + } + + cable->link.port = port; + cable->params = cable_params; + cable->chain = NULL; + + return 0; +} + +void +generic_parport_free( cable_t *cable ) +{ + cable->link.port->driver->parport_free( cable->link.port ); + free( cable->params ); + free( cable ); +} + +void +generic_parport_done( cable_t *cable ) +{ + parport_close( cable->link.port ); +} + +void +generic_parport_help( const char *cablename ) +{ + printf( _( + "Usage: cable %s parallel PORTADDR\n" +#if HAVE_LINUX_PPDEV_H + " or: cable %s ppdev PPDEV\n" +#endif +#if HAVE_DEV_PPBUS_PPI_H + " or: cable %s ppi PPIDEV\n" +#endif + "\n" + "PORTADDR parallel port address (e.g. 0x378)\n" +#if HAVE_LINUX_PPDEV_H + "PPDEF ppdev device (e.g. /dev/parport0)\n" +#endif +#if HAVE_DEV_PPBUS_PPI_H + "PPIDEF ppi device (e.g. /dev/ppi0)\n" +#endif + "\n" + ), +#if HAVE_LINUX_PPDEV_H + cablename, +#endif +#if HAVE_DEV_PPBUS_PPI_H + cablename, +#endif + cablename + ); +} + diff --git a/jtag/src/tap/cable/generic_parport.h b/jtag/src/tap/cable/generic_parport.h new file mode 100644 index 00000000..41c5c2ae --- /dev/null +++ b/jtag/src/tap/cable/generic_parport.h @@ -0,0 +1,36 @@ +/* + * $Id: generic.h 1002 2008-02-10 09:50:59Z kawk $ + * + * 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 , 2003. + * + */ + +#ifndef GENERIC_PARPORT_H +#define GENERIC_PARPORT_H + +#include "cable.h" +#include "parport.h" + +int generic_parport_connect( char *params[], cable_t *cable ); +void generic_parport_free( cable_t *cable ); +void generic_parport_done( cable_t *cable ); +void generic_parport_help( const char *name ); + +#endif /* GENERIC_H */ diff --git a/jtag/src/tap/cable/generic_usbconn.c b/jtag/src/tap/cable/generic_usbconn.c new file mode 100644 index 00000000..dd2aab91 --- /dev/null +++ b/jtag/src/tap/cable/generic_usbconn.c @@ -0,0 +1,176 @@ +/* + * $Id: generic.c 1003 2008-02-10 10:00:30Z kawk $ + * + * 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 , 2003. + * + */ + +#include "sysdep.h" + +#include +#include +#include + +#include "cable.h" +#include "chain.h" +#include "generic.h" +#include "generic_usbconn.h" + +#include + +#undef VERBOSE + +#ifdef HAVE_LIBUSB +extern usbconn_cable_t usbconn_cable_xpc_int; +extern usbconn_cable_t usbconn_cable_xpc_ext; +extern usbconn_cable_t usbconn_cable_jlink; +#endif + +usbconn_cable_t *usbconn_cables[] = +{ +#ifdef HAVE_LIBUSB + &usbconn_cable_xpc_int, + &usbconn_cable_xpc_ext, + &usbconn_cable_jlink, +#endif + NULL +}; + +int +generic_usbconn_connect( char *params[], cable_t *cable ) +{ + usbconn_cable_t user_specified = { + NULL, /* no name */ + NULL, /* no string pattern */ + NULL, /* no specific driver */ + -1, /* no VID */ + -1, /* no PID */ + }; + + int paramc = cmd_params( params ); + generic_params_t *cable_params; + usbconn_t *conn = NULL; + int i; + + cable_params = malloc( sizeof(generic_params_t) ); + + if (!cable_params) + { + free( cable ); + return 4; + } + + if(strcasecmp(params[0], "usb") != 0) + { + user_specified.name = params[0]; + } + + /* parse arguments beyond the cable name */ + for (i = 1; i < paramc; i++) + { + if(strncasecmp("pid=", params[i], 4) == 0) + { + user_specified.pid = strtol( params[i] + 4, NULL, 10 ); + } + else if(strncasecmp("vid=", params[i], 4) == 0) + { + user_specified.vid = strtol( params[i] + 4, NULL, 10 ); + } + else if(strncasecmp("desc=", params[i], 5) == 0) + { + user_specified.desc = params[i] + 5; + } + else if(strncasecmp("driver=", params[i], 7) == 0) + { + user_specified.driver = params[i] + 7; + } + } + + /* search usbconn driver list */ + for (i = 0; usbconn_drivers[i] && !conn; i++) + { + if ((user_specified.driver == NULL) + || (strcasecmp(user_specified.name, usbconn_drivers[i]->type) == 0)) + { + int j; + + /* search cable list */ + for (j = 0; usbconn_cables[j] && !conn; j++) + { + if((user_specified.name == NULL) + || (strcasecmp(user_specified.name, usbconn_cables[j]->name) == 0)) + { + if(strcasecmp(usbconn_cables[j]->driver, usbconn_drivers[i]->type) == 0) + { + usbconn_cable_t cable_try = *(usbconn_cables[j]); + + if(user_specified.vid >= 0) cable_try.vid = user_specified.vid; + if(user_specified.pid >= 0) cable_try.pid = user_specified.pid; + if(user_specified.desc != 0) cable_try.desc = user_specified.desc; + + conn = usbconn_drivers[i]->connect( (const char **) ¶ms[1], + paramc - 1, &cable_try ); + } + } + } + } + } + + if (!conn) { + printf( _("Couldn't connect to suitable USB device.\n") ); + return 2; + } + + cable->link.usb = conn; + cable->params = cable_params; + cable->chain = NULL; + + return 0; +} + +void +generic_usbconn_free( cable_t *cable ) +{ + cable->link.usb->driver->free( cable->link.usb ); + free( cable->params ); + free( cable ); +} + +void +generic_usbconn_done( cable_t *cable ) +{ + usbconn_close( cable->link.usb ); +} + +void +generic_usbconn_help( const char *cablename ) +{ + printf( _( + "Usage: cable %s [vid=VID] [pid=PID] [desc=DESC] [...]\n" + "\n" + "VID USB Device Vendor ID (hex, e.g. 0abc)\n" + "PID USB Device Product ID (hex, e.g. 0abc)\n" + "DESC Some string to match in description or serial no.\n" + "\n" + ), + cablename + ); +} + diff --git a/jtag/src/tap/cable/generic_usbconn.h b/jtag/src/tap/cable/generic_usbconn.h new file mode 100644 index 00000000..25a75b61 --- /dev/null +++ b/jtag/src/tap/cable/generic_usbconn.h @@ -0,0 +1,36 @@ +/* + * $Id: generic.h 1002 2008-02-10 09:50:59Z kawk $ + * + * 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 , 2003. + * + */ + +#ifndef GENERIC_USBCONN_H +#define GENERIC_USBCONN_H + +#include "cable.h" +#include "usbconn.h" + +int generic_usbconn_connect( char *params[], cable_t *cable ); +void generic_usbconn_done( cable_t *cable ); +void generic_usbconn_help( const char *name ); +void generic_usbconn_free( cable_t *cable ); + +#endif /* GENERIC_H */ diff --git a/jtag/src/tap/cable/jlink.c b/jtag/src/tap/cable/jlink.c new file mode 100644 index 00000000..3c685de6 --- /dev/null +++ b/jtag/src/tap/cable/jlink.c @@ -0,0 +1,503 @@ +/* + * $Id: jlink.c,v 1.8 2003/08/19 08:42:20 telka Exp $ + * + * Segger J-Link cable driver + * + * Large portions of code were taken from the OpenOCD driver written by + * Juergen Stuber, which in turn was based on Dominic Rath's and Benedikt + * Sauter's usbprog.c. Therefore most of this code is actually + * + * Copyright (C) 2007 Juergen Stuber + * + * Modified to work in UrJTAG by K. Waschk in 2008. + * + * 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. + * + */ + + +#include "generic.h" +#include "generic_usbconn.h" + +#include "usbconn.h" +#include "usbconn/libusb.h" + +/* ---------------------------------------------------------------------- */ + + +#include "sysdep.h" + +#include "cable.h" +#include "chain.h" + +#include "jtag.h" + +#include +#include + +#define INFO printf +#define ERROR printf +#define DEBUG printf + +#define JLINK_WRITE_ENDPOINT 0x02 +#define JLINK_READ_ENDPOINT 0x81 + +#define JLINK_USB_TIMEOUT 100 + +#define JLINK_IN_BUFFER_SIZE 2064 +#define JLINK_OUT_BUFFER_SIZE 2064 + +/* Global USB buffers */ +static char usb_in_buffer[JLINK_IN_BUFFER_SIZE]; +static char usb_out_buffer[JLINK_OUT_BUFFER_SIZE]; + +/* Constants for JLink command */ +#define JLINK_SPEED_COMMAND 0x05 +#define JLINK_TAP_SEQUENCE_COMMAND 0xcd +#define JLINK_SET_SRST_LOW_COMMAND 0xdc +#define JLINK_SET_SRST_HIGH_COMMAND 0xdd +#define JLINK_SET_TRST_LOW_COMMAND 0xde +#define JLINK_SET_TRST_HIGH_COMMAND 0xdf + +#define JLINK_MAX_SPEED 12000 + + +/* Queue command functions */ +static void jlink_reset( cable_t *cable, int trst, int srst); +static void jlink_simple_command( cable_t *cable, uint8_t command ); + +/* J-Link tap buffer functions */ +static void jlink_tap_init(); +static int jlink_tap_execute(); +static void jlink_tap_append_step(int tms, int tdi); + +/* Jlink lowlevel functions */ +static int jlink_usb_message( cable_t *cable, int out_length, int in_length); +static int jlink_usb_write( cable_t *cable, unsigned int out_length); +static int jlink_usb_read( cable_t *cable ); +static void jlink_debug_buffer(uint8_t *buffer, int length); + + + +void jlink_set_frequency( cable_t *cable, uint32_t frequency ) +{ + int result; + int speed = frequency / 1E3; + + if (1 <= speed && speed <= JLINK_MAX_SPEED) + { + usb_out_buffer[0] = JLINK_SPEED_COMMAND; + usb_out_buffer[1] = (speed >> 0) & 0xff; + usb_out_buffer[2] = (speed >> 8) & 0xff; + + result = jlink_usb_write( cable, 3 ); + + if (result != 3) + { + ERROR("J-Link setting speed failed (%d)\n", result); + } + } + else + { + INFO("Requested speed %dkHz exceeds maximum of %dkHz, ignored\n", + speed, JLINK_MAX_SPEED); + } +} + +void jlink_reset( cable_t *cable, int trst, int srst) +{ + DEBUG("trst: %i, srst: %i\n", trst, srst); + + /* Signals are active low */ + if (trst == 0) + { + jlink_simple_command( cable, JLINK_SET_TRST_HIGH_COMMAND); + } + else if (trst == 1) + { + jlink_simple_command( cable, JLINK_SET_TRST_LOW_COMMAND); + } + + if (srst == 0) + { + jlink_simple_command( cable, JLINK_SET_SRST_HIGH_COMMAND); + } + else if (srst == 1) + { + jlink_simple_command( cable, JLINK_SET_SRST_LOW_COMMAND); + } +} + + +static void jlink_simple_command( cable_t *cable, uint8_t command) +{ + int result; + + DEBUG("simple_command: 0x%02x\n", command); + + usb_out_buffer[0] = command; + result = jlink_usb_write( cable, 1 ); + + if (result != 1) + { + ERROR("J-Link command 0x%02x failed (%d)\n", command, result); + } +} + +/***************************************************************************/ +/* J-Link tap functions */ + +/* We use the maximal value observed */ +#define JLINK_TAP_BUFFER_SIZE 390 + +static int tap_length; +static uint8_t tms_buffer[JLINK_TAP_BUFFER_SIZE]; +static uint8_t tdi_buffer[JLINK_TAP_BUFFER_SIZE]; + +static int last_tdo; + +static void jlink_tap_init() +{ + tap_length = 0; +} + +static void jlink_tap_append_step(int tms, int tdi) +{ + int index = tap_length >> 3; + + if (index < JLINK_TAP_BUFFER_SIZE) + { + int bit_index = tap_length & 7; + uint8_t bit = 1 << bit_index; + + if(bit_index == 0) + { + tms_buffer[index] = 0; + tdi_buffer[index] = 0; + }; + + if(tms) tms_buffer[index] |= bit; + if(tdi) tdi_buffer[index] |= bit; + + tap_length++; + } + else + { + ERROR("jlink_tap_append_step, overflow\n"); + } +} + +/* Pad and send a tap sequence to the device, and receive the answer. + * For the purpose of padding we assume that we are in idle or pause state. */ +static int jlink_tap_execute( cable_t *cable ) +{ + int byte_length; + int tms_offset; + int tdi_offset; + int i; + int result; + + if (tap_length > 0) + { + byte_length = (tap_length + 7) >> 3; + usb_out_buffer[0] = JLINK_TAP_SEQUENCE_COMMAND; + usb_out_buffer[1] = (tap_length >> 0) & 0xff; + usb_out_buffer[2] = (tap_length >> 8) & 0xff; + + tms_offset = 3; + for (i = 0; i < byte_length; i++) + { + usb_out_buffer[tms_offset + i] = tms_buffer[i]; + } + + tdi_offset = tms_offset + byte_length; + for (i = 0; i < byte_length; i++) + { + usb_out_buffer[tdi_offset + i] = tdi_buffer[i]; + } + + result = jlink_usb_message( + cable, + 3 + 2 * byte_length, + byte_length); + + if (result == byte_length) + { + int bit_index = (tap_length - 1) & 7; + uint8_t bit = 1 << bit_index; + + last_tdo = ((usb_in_buffer[byte_length-1]) & bit ) ? 1 : 0; + } + else + { + ERROR( + "jlink_tap_execute, wrong result %d, expected %d", + result, + byte_length); + + return -2; + } + + jlink_tap_init(); + } + return 0; +} + +/* ---------------------------------------------------------------------- */ + +/* Send a message and receive the reply. */ +static int jlink_usb_message( + cable_t *cable, + int out_length, + int in_length) +{ + int result; + + result = jlink_usb_write( cable, out_length ); + if (result == out_length) + { + result = jlink_usb_read( cable ); + if (result == in_length) + { + return result; + } + else + { + ERROR( + "usb_bulk_read failed (requested=%d, result=%d)\n", + in_length, + result); + + return -1; + } + } + else + { + ERROR( + "usb_bulk_write failed (requested=%d, result=%d)\n", + out_length, + result); + + return -1; + } +} + +/* ---------------------------------------------------------------------- */ + +/* Write data from out_buffer to USB. */ +static int jlink_usb_write( cable_t *cable, unsigned int out_length ) +{ + int result; + struct usb_dev_handle *jlink; + jlink = ((libusb_param_t*)(cable->link.usb->params))->handle; + + if (out_length > JLINK_OUT_BUFFER_SIZE) + { + ERROR("jlink_jtag_write illegal out_length=%d (max=%d)\n", out_length, + JLINK_OUT_BUFFER_SIZE); + + return -1; + } + + result = usb_bulk_write( + jlink, + JLINK_WRITE_ENDPOINT, + usb_out_buffer, + out_length, + JLINK_USB_TIMEOUT); + + DEBUG("jlink_usb_write, out_length = %d, result = %d\n", out_length, result); + jlink_debug_buffer(usb_out_buffer, out_length); + return result; +} + +/* ---------------------------------------------------------------------- */ + +/* Read data from USB into in_buffer. */ +static int jlink_usb_read( cable_t *cable ) +{ + struct usb_dev_handle *jlink; + jlink = ((libusb_param_t*)(cable->link.usb->params))->handle; + + int result = usb_bulk_read( + jlink, + JLINK_READ_ENDPOINT, + usb_in_buffer, + JLINK_IN_BUFFER_SIZE, + JLINK_USB_TIMEOUT); + + DEBUG("jlink_usb_read, result = %d\n", result); + jlink_debug_buffer(usb_in_buffer, result); + return result; +} + +/* ---------------------------------------------------------------------- */ + +#define BYTES_PER_LINE 16 + +static void jlink_debug_buffer(uint8_t *buffer, int length) +{ + char line[81]; + char s[4]; + int i; + int j; + + for (i = 0; i < length; i += BYTES_PER_LINE) + { + snprintf(line, 5, "%04x", i); + for (j = i; j < i + BYTES_PER_LINE && j < length; j++) + { + snprintf(s, 4, " %02x", buffer[j]); + strcat(line, s); + } + DEBUG(line); + DEBUG("\n"); + } +} + +/* ---------------------------------------------------------------------- */ + +static int +jlink_init( cable_t *cable ) +{ + int result; + struct usb_dev_handle *jlink; + + if (usbconn_open( cable->link.usb )) return -1; + + jlink = ((libusb_param_t*)(cable->link.usb->params))->handle; + + jlink_tap_init(); + + result = jlink_usb_read( cable ); + if (result != 2 || usb_in_buffer[0] != 0x07 || usb_in_buffer[1] != 0x00) + { + INFO("J-Link initial read failed, don't worry (result=%d)\n", result); + } + + INFO("J-Link JTAG Interface ready\n"); + + jlink_set_frequency( cable, 4E6 ); + jlink_reset( cable, 0, 0); + jlink_tap_init(); + + + PARAM_TRST(cable) = 1; + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +int tdo_cache; + +static void +jlink_clock( cable_t *cable, int tms, int tdi, int n ) +{ + int i; + + for (i = 0; i < n; i++) + { + jlink_tap_append_step(tms, tdi); + } + jlink_tap_execute( cable ); +} + +/* ---------------------------------------------------------------------- */ + +static int +jlink_get_tdo( cable_t *cable ) +{ + // TODO: This is the TDO _before_ last clock occured + // ... Anyone knows how to get the current TDO state? + + return last_tdo; +} + +/* ---------------------------------------------------------------------- */ + +void +jlink_copy_out_data( cable_t *cable, int len, int offset, char *buf ) +{ + int i; + for(i=0;i>3; + buf[offset+i] = (usb_in_buffer[byte] & bit) ? 1 : 0; + } +} + +int +jlink_transfer( cable_t *cable, int len, char *in, char *out ) +{ + int i,j; + + for(j=0, i=0; i= 8*JLINK_TAP_BUFFER_SIZE) + { + jlink_tap_execute( cable ); + if(out) jlink_copy_out_data( cable, i-j, j, out); + j = i; + } + }; + if(tap_length > 0) + { + jlink_tap_execute( cable ); + if(out) jlink_copy_out_data( cable, i-j, j, out); + } + + return i; +} + +/* ---------------------------------------------------------------------- */ + +static int +jlink_set_trst( cable_t *cable, int trst ) +{ + return 1; +} + +cable_driver_t jlink_cable_driver = { + "jlink", + N_("Segger/IAR J-Link, Atmel SAM-ICE and others."), + generic_usbconn_connect, + generic_disconnect, + generic_usbconn_free, + jlink_init, + generic_usbconn_done, + jlink_set_frequency, + jlink_clock, + jlink_get_tdo, + jlink_transfer, + jlink_set_trst, + generic_get_trst, + generic_flush_using_transfer, + generic_usbconn_help +}; + +usbconn_cable_t usbconn_cable_jlink = { + "jlink", /* cable name */ + NULL, /* string pattern, not used */ + "libusb", /* usbconn driver */ + 0x1366, /* VID */ + 0x0101 /* PID */ +}; + + diff --git a/jtag/src/tap/cable/keithkoep.c b/jtag/src/tap/cable/keithkoep.c index 3e23222c..b8528e6c 100644 --- a/jtag/src/tap/cable/keithkoep.c +++ b/jtag/src/tap/cable/keithkoep.c @@ -33,7 +33,7 @@ #include "chain.h" #include "generic.h" - +#include "generic_parport.h" /* * data D[7:0] (pins 9:2) @@ -66,10 +66,10 @@ static int keithkoep_init( cable_t *cable ) { - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; - parport_set_control( cable->port, 1 << TRST ); + parport_set_control( cable->link.port, 1 << TRST ); PARAM_TRST(cable) = 1; return 0; @@ -84,9 +84,9 @@ keithkoep_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (0 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); - parport_set_data( cable->port, (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (1 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); } } @@ -94,9 +94,9 @@ keithkoep_clock( cable_t *cable, int tms, int tdi, int n ) static int keithkoep_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, 0 << TCK ); + parport_set_data( cable->link.port, 0 << TCK ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int @@ -104,18 +104,18 @@ keithkoep_set_trst( cable_t *cable, int trst ) { PARAM_TRST(cable) = trst ? 1 : 0; - parport_set_control( cable->port, PARAM_TRST(cable) << TRST ); + parport_set_control( cable->link.port, PARAM_TRST(cable) << TRST ); return PARAM_TRST(cable); } cable_driver_t keithkoep_cable_driver = { "KeithKoep", N_("Keith & Koep JTAG cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, keithkoep_init, - generic_done, + generic_parport_done, generic_set_frequency, keithkoep_clock, keithkoep_get_tdo, @@ -123,5 +123,5 @@ cable_driver_t keithkoep_cable_driver = { keithkoep_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/lattice.c b/jtag/src/tap/cable/lattice.c index a414ea21..ddcff4b0 100644 --- a/jtag/src/tap/cable/lattice.c +++ b/jtag/src/tap/cable/lattice.c @@ -30,6 +30,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" /* * 0 - STROBE (pin 1) @@ -53,7 +54,7 @@ static int lattice_init( cable_t *cable ) { - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; PARAM_TRST(cable) = 1; @@ -70,9 +71,9 @@ lattice_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (0 << TCK) | (tms << TMS) | (tdi << TDI) | (1 << TRST) ); + parport_set_data( cable->link.port, (0 << TCK) | (tms << TMS) | (tdi << TDI) | (1 << TRST) ); cable_wait( cable ); - parport_set_data( cable->port, (1 << TCK) | (tms << TMS) | (tdi << TDI) | (1 << TRST) ); + parport_set_data( cable->link.port, (1 << TCK) | (tms << TMS) | (tdi << TDI) | (1 << TRST) ); cable_wait( cable ); } } @@ -80,25 +81,25 @@ lattice_clock( cable_t *cable, int tms, int tdi, int n ) static int lattice_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, (0 << TCK) | (1 << TRST) ); + parport_set_data( cable->link.port, (0 << TCK) | (1 << TRST) ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int lattice_set_trst( cable_t *cable, int trst ) { - return parport_set_data( cable->port, trst << TRST ); + return parport_set_data( cable->link.port, trst << TRST ); } cable_driver_t lattice_cable_driver = { "Lattice", N_("Lattice Parallel Port JTAG Cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, lattice_init, - generic_done, + generic_parport_done, generic_set_frequency, lattice_clock, lattice_get_tdo, @@ -106,5 +107,5 @@ cable_driver_t lattice_cable_driver = { lattice_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/mpcbdm.c b/jtag/src/tap/cable/mpcbdm.c index 95afd4c3..574e197c 100644 --- a/jtag/src/tap/cable/mpcbdm.c +++ b/jtag/src/tap/cable/mpcbdm.c @@ -34,6 +34,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" /* * data D[7:0] (pins 9:2) @@ -63,10 +64,10 @@ static int mpcbdm_init( cable_t *cable ) { - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; - parport_set_control( cable->port, 0 << TRST ); + parport_set_control( cable->link.port, 0 << TRST ); PARAM_TRST(cable) = 1; return 0; @@ -81,9 +82,9 @@ mpcbdm_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (0 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); - parport_set_data( cable->port, (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (1 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); } } @@ -91,9 +92,9 @@ mpcbdm_clock( cable_t *cable, int tms, int tdi, int n ) static int mpcbdm_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, 0 << TCK ); + parport_set_data( cable->link.port, 0 << TCK ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int @@ -101,18 +102,18 @@ mpcbdm_set_trst( cable_t *cable, int trst ) { PARAM_TRST(cable) = trst ? 1 : 0; - parport_set_control( cable->port, (PARAM_TRST(cable) ^ 1) << TRST ); + parport_set_control( cable->link.port, (PARAM_TRST(cable) ^ 1) << TRST ); return PARAM_TRST(cable); } cable_driver_t mpcbdm_cable_driver = { "MPCBDM", N_("Mpcbdm JTAG cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, mpcbdm_init, - generic_done, + generic_parport_done, generic_set_frequency, mpcbdm_clock, mpcbdm_get_tdo, @@ -120,5 +121,5 @@ cable_driver_t mpcbdm_cable_driver = { mpcbdm_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/triton.c b/jtag/src/tap/cable/triton.c index 256462f2..6a9f2e3f 100644 --- a/jtag/src/tap/cable/triton.c +++ b/jtag/src/tap/cable/triton.c @@ -43,6 +43,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" /* * data D[7:0] (pins 9:2) @@ -68,7 +69,7 @@ static int triton_init( cable_t *cable ) { - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; PARAM_TRST(cable) = 1; @@ -86,9 +87,9 @@ triton_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (PARAM_SRESET(cable) << SRESET) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (PARAM_SRESET(cable) << SRESET) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (PARAM_SRESET(cable) << SRESET) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (PARAM_SRESET(cable) << SRESET) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); cable_wait( cable ); } } @@ -96,9 +97,9 @@ triton_clock( cable_t *cable, int tms, int tdi, int n ) static int triton_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (PARAM_SRESET(cable) << SRESET) | (0 << TCK) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (PARAM_SRESET(cable) << SRESET) | (0 << TCK) ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int @@ -106,18 +107,18 @@ triton_set_trst( cable_t *cable, int trst ) { PARAM_TRST(cable) = trst ? 1 : 0; - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (PARAM_SRESET(cable) << SRESET) ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (PARAM_SRESET(cable) << SRESET) ); return PARAM_TRST(cable); } cable_driver_t triton_cable_driver = { "TRITON", N_("Ka-Ro TRITON Starterkit II (PXA255/250) JTAG Cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, triton_init, - generic_done, + generic_parport_done, generic_set_frequency, triton_clock, triton_get_tdo, @@ -125,5 +126,5 @@ cable_driver_t triton_cable_driver = { triton_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/usbblaster.c b/jtag/src/tap/cable/usbblaster.c index dd820317..4b605cb7 100644 --- a/jtag/src/tap/cable/usbblaster.c +++ b/jtag/src/tap/cable/usbblaster.c @@ -32,6 +32,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" #define TCK 0 #define TMS 1 @@ -47,14 +48,14 @@ usbblaster_init( cable_t *cable ) { int i; - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; for(i=0;i<64;i++) - parport_set_data( cable->port, 0 ); + parport_set_data( cable->link.port, 0 ); - parport_set_control( cable->port, 1 ); // flush - parport_set_control( cable->port, 0 ); // noflush + parport_set_control( cable->link.port, 1 ); // flush + parport_set_control( cable->link.port, 0 ); // noflush return 0; } @@ -70,29 +71,29 @@ usbblaster_clock( cable_t *cable, int tms, int tdi, int n ) // printf("clock: %d %d %d\n", tms, tdi, n); for (i = 0; i < n; i++) { - parport_set_data( cable->port, OTHERS | (0 << TCK) | tms | tdi ); - parport_set_data( cable->port, OTHERS | (1 << TCK) | tms | tdi ); - parport_set_control( cable->port, 1 ); // flush - parport_set_control( cable->port, 0 ); // noflush + parport_set_data( cable->link.port, OTHERS | (0 << TCK) | tms | tdi ); + parport_set_data( cable->link.port, OTHERS | (1 << TCK) | tms | tdi ); + parport_set_control( cable->link.port, 1 ); // flush + parport_set_control( cable->link.port, 0 ); // noflush } } static int usbblaster_get_tdo( cable_t *cable ) { - parport_set_control( cable->port, 0 ); // noflush - parport_set_data( cable->port, OTHERS ); /* TCK low */ - parport_set_data( cable->port, OTHERS | (1 << READ) ); /* TCK low */ - parport_set_control( cable->port, 1 ); // flush - parport_set_control( cable->port, 0 ); // noflush + parport_set_control( cable->link.port, 0 ); // noflush + parport_set_data( cable->link.port, OTHERS ); /* TCK low */ + parport_set_data( cable->link.port, OTHERS | (1 << READ) ); /* TCK low */ + parport_set_control( cable->link.port, 1 ); // flush + parport_set_control( cable->link.port, 0 ); // noflush #if 0 { - char x = ( parport_get_data( cable->port ) & (1 << TDO)) ? 1 : 0; + char x = ( parport_get_data( cable->link.port ) & (1 << TDO)) ? 1 : 0; printf("GetTDO %d\n", x); return x; } #else - return ( parport_get_data( cable->port ) & (1 << TDO)) ? 1 : 0; + return ( parport_get_data( cable->link.port ) & (1 << TDO)) ? 1 : 0; #endif } @@ -107,8 +108,8 @@ usbblaster_transfer( cable_t *cable, int len, char *in, char *out ) { int in_offset = 0; int out_offset = 0; - parport_set_control( cable->port, 0 ); - parport_set_data( cable->port, OTHERS ); /* TCK low */ + parport_set_control( cable->link.port, 0 ); + parport_set_data( cable->link.port, OTHERS ); /* TCK low */ #if 0 { @@ -126,27 +127,27 @@ usbblaster_transfer( cable_t *cable, int len, char *in, char *out ) if(chunkbytes > 63) chunkbytes = 63; if(out) - parport_set_data( cable->port,(1<link.port,(1<port,(1<link.port,(1<port, b ); + parport_set_data( cable->link.port, b ); }; if(out) { - parport_set_control( cable->port, 1 ); // flush - parport_set_control( cable->port, 0 ); + parport_set_control( cable->link.port, 1 ); // flush + parport_set_control( cable->link.port, 0 ); for(i=0; iport ); + unsigned char b = parport_get_data( cable->link.port ); #if 0 printf("read byte: %02X\n", b); #endif @@ -159,18 +160,18 @@ usbblaster_transfer( cable_t *cable, int len, char *in, char *out ) while(len > in_offset) { char tdi = in[in_offset++] ? 1 : 0; - parport_set_data( cable->port, OTHERS ); /* TCK low */ - if(out) parport_set_data( cable->port, OTHERS | (1 << READ) | (tdi << TDI)); - parport_set_data( cable->port, OTHERS | (1 << TCK) | (tdi << TDI)); + parport_set_data( cable->link.port, OTHERS ); /* TCK low */ + if(out) parport_set_data( cable->link.port, OTHERS | (1 << READ) | (tdi << TDI)); + parport_set_data( cable->link.port, OTHERS | (1 << TCK) | (tdi << TDI)); } if(out) { - parport_set_control( cable->port, 1 ); // flush - parport_set_control( cable->port, 0 ); + parport_set_control( cable->link.port, 1 ); // flush + parport_set_control( cable->link.port, 0 ); while(len > out_offset) - out[out_offset++] = ( parport_get_data( cable->port ) & (1 << TDO)) ? 1 : 0; + out[out_offset++] = ( parport_get_data( cable->link.port ) & (1 << TDO)) ? 1 : 0; #if 0 { @@ -209,16 +210,16 @@ usbblaster_flush( cable_t *cable, cable_flush_amount_t how_much ) // printf("clock: %d %d %d\n", tms, tdi, m); for(; m>0; m--) { - parport_set_data( cable->port, OTHERS | tms | tdi ); - parport_set_data( cable->port, OTHERS | (1 << TCK) | tms | tdi ); + parport_set_data( cable->link.port, OTHERS | tms | tdi ); + parport_set_data( cable->link.port, OTHERS | (1 << TCK) | tms | tdi ); to_send += 2; } break; } case CABLE_GET_TDO: { - parport_set_data( cable->port, OTHERS ); /* TCK low */ - parport_set_data( cable->port, OTHERS | (1 << READ) ); /* TCK low */ + parport_set_data( cable->link.port, OTHERS ); /* TCK low */ + parport_set_data( cable->link.port, OTHERS | (1 << READ) ); /* TCK low */ // printf("get_tdo\n"); to_send += 2; break; @@ -234,14 +235,14 @@ usbblaster_flush( cable_t *cable, cable_flush_amount_t how_much ) #if 0 if(cable->todo.num_items > 0 && cable->todo.data[i].action == CABLE_TRANSFER) { - parport_set_data( cable->port, OTHERS ); /* TCK low */ + parport_set_data( cable->link.port, OTHERS ); /* TCK low */ }; #endif if(to_send > 0) { - parport_set_control( cable->port, 1 ); // flush - parport_set_control( cable->port, 0 ); + parport_set_control( cable->link.port, 1 ); // flush + parport_set_control( cable->link.port, 0 ); } while(j!=i) @@ -250,7 +251,7 @@ usbblaster_flush( cable_t *cable, cable_flush_amount_t how_much ) { case CABLE_GET_TDO: { - int tdo = (parport_get_data( cable->port ) & (1<link.port ) & (1<done) ); cable->done.data[m].action = CABLE_GET_TDO; cable->done.data[m].arg.value.tdo = tdo; @@ -321,11 +322,11 @@ usbblaster_help( const char *cablename ) cable_driver_t usbblaster_cable_driver = { "UsbBlaster", N_("Altera USB-Blaster Cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, usbblaster_init, - generic_done, + generic_parport_done, usbblaster_set_frequency, usbblaster_clock, usbblaster_get_tdo, diff --git a/jtag/src/tap/cable/vision_ep9307.c b/jtag/src/tap/cable/vision_ep9307.c index 3f94dd42..c8adb307 100644 --- a/jtag/src/tap/cable/vision_ep9307.c +++ b/jtag/src/tap/cable/vision_ep9307.c @@ -206,7 +206,7 @@ ep9307_connect( char *params[], cable_t *cable ) return 4; } - cable->port = NULL; + cable->link.port = NULL; cable->params = cable_params; cable->chain = NULL; diff --git a/jtag/src/tap/cable/wiggler.c b/jtag/src/tap/cable/wiggler.c index 3b5a99bd..77404769 100644 --- a/jtag/src/tap/cable/wiggler.c +++ b/jtag/src/tap/cable/wiggler.c @@ -38,6 +38,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" #include @@ -177,11 +178,11 @@ wiggler_connect( char *params[], cable_t *cable ) if ( cmd_params ( params ) == 4 ) { /* acquire optional parameter for bit<->pin mapping */ param_bitmap = params[3]; - /* generic_connect() shouldn't see this parameter */ + /* generic_parport_connect() shouldn't see this parameter */ params[3] = NULL; } - if ( ( result = generic_connect( params, cable ) ) != 0) + if ( ( result = generic_parport_connect( params, cable ) ) != 0) return result; if ( param_bitmap ) @@ -218,11 +219,11 @@ wiggler_init( cable_t *cable ) { int data; - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; - if ((data = parport_get_data( cable->port )) < 0) { - if (parport_set_data( cable->port, (PRM_TRST_ACT(cable) | PRM_TRST_INACT(cable)) | PRM_UNUSED_BITS(cable))) + if ((data = parport_get_data( cable->link.port )) < 0) { + if (parport_set_data( cable->link.port, (PRM_TRST_ACT(cable) | PRM_TRST_INACT(cable)) | PRM_UNUSED_BITS(cable))) return -1; PRM_TRST_LVL(cable) = PRM_TRST_ACT(cable) | PRM_TRST_INACT(cable); } else @@ -240,13 +241,13 @@ wiggler_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, PRM_TRST_LVL(cable) | + parport_set_data( cable->link.port, PRM_TRST_LVL(cable) | PRM_TCK_INACT(cable) | (tms ? PRM_TMS_ACT(cable) : PRM_TMS_INACT(cable)) | (tdi ? PRM_TDI_ACT(cable) : PRM_TDI_INACT(cable)) | PRM_UNUSED_BITS(cable) ); cable_wait( cable ); - parport_set_data( cable->port, PRM_TRST_LVL(cable) | + parport_set_data( cable->link.port, PRM_TRST_LVL(cable) | PRM_TCK_ACT(cable) | (tms ? PRM_TMS_ACT(cable) : PRM_TMS_INACT(cable)) | (tdi ? PRM_TDI_ACT(cable) : PRM_TDI_INACT(cable)) | @@ -258,11 +259,11 @@ wiggler_clock( cable_t *cable, int tms, int tdi, int n ) static int wiggler_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, PRM_TRST_LVL(cable) | + parport_set_data( cable->link.port, PRM_TRST_LVL(cable) | PRM_TCK_INACT(cable) | PRM_UNUSED_BITS(cable) ); cable_wait( cable ); - return (parport_get_status( cable->port ) & (PRM_TDO_ACT(cable) | PRM_TDO_INACT(cable))) ^ + return (parport_get_status( cable->link.port ) & (PRM_TDO_ACT(cable) | PRM_TDO_INACT(cable))) ^ PRM_TDO_ACT(cable) ? 0 : 1; } @@ -271,7 +272,7 @@ wiggler_set_trst( cable_t *cable, int trst ) { PRM_TRST_LVL(cable) = trst ? PRM_TRST_ACT(cable) : PRM_TRST_INACT(cable); - parport_set_data( cable->port, PRM_TRST_LVL(cable) | + parport_set_data( cable->link.port, PRM_TRST_LVL(cable) | PRM_UNUSED_BITS(cable) ); return PRM_TRST_LVL(cable) ^ PRM_TRST_ACT(cable) ? 0 : 1; } @@ -321,9 +322,9 @@ cable_driver_t wiggler_cable_driver = { N_("Macraigor Wiggler JTAG Cable"), wiggler_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, wiggler_init, - generic_done, + generic_parport_done, generic_set_frequency, wiggler_clock, wiggler_get_tdo, @@ -339,9 +340,9 @@ cable_driver_t igloo_cable_driver = { N_("Excelpoint IGLOO JTAG Cable"), wiggler_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, wiggler_init, - generic_done, + generic_parport_done, generic_set_frequency, wiggler_clock, wiggler_get_tdo, diff --git a/jtag/src/tap/cable/wiggler2.c b/jtag/src/tap/cable/wiggler2.c index 9796c2fa..c7bd06dc 100644 --- a/jtag/src/tap/cable/wiggler2.c +++ b/jtag/src/tap/cable/wiggler2.c @@ -41,6 +41,7 @@ #include "chain.h" #include "generic.h" +#include "generic_parport.h" /* * data D[7:0] (pins 9:2) @@ -69,11 +70,11 @@ wiggler2_init( cable_t *cable ) { int data; - if (parport_open( cable->port )) + if (parport_open( cable->link.port )) return -1; - if ((data = parport_get_data( cable->port )) < 0) { - if (parport_set_data( cable->port, (0 << TRST) | UNUSED_BITS )) + if ((data = parport_get_data( cable->link.port )) < 0) { + if (parport_set_data( cable->link.port, (0 << TRST) | UNUSED_BITS )) return -1; PARAM_TRST(cable) = 1; } else @@ -91,9 +92,9 @@ wiggler2_clock( cable_t *cable, int tms, int tdi, int n ) tdi = tdi ? 1 : 0; for (i = 0; i < n; i++) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) | UNUSED_BITS ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | (tms << TMS) | (tdi << TDI) | UNUSED_BITS ); cable_wait( cable ); - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) | UNUSED_BITS ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (1 << TCK) | (tms << TMS) | (tdi << TDI) | UNUSED_BITS ); cable_wait( cable ); } } @@ -101,9 +102,9 @@ wiggler2_clock( cable_t *cable, int tms, int tdi, int n ) static int wiggler2_get_tdo( cable_t *cable ) { - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | UNUSED_BITS ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | (0 << TCK) | UNUSED_BITS ); cable_wait( cable ); - return (parport_get_status( cable->port ) >> TDO) & 1; + return (parport_get_status( cable->link.port ) >> TDO) & 1; } static int @@ -111,18 +112,18 @@ wiggler2_set_trst( cable_t *cable, int trst ) { PARAM_TRST(cable) = trst ? 1 : 0; - parport_set_data( cable->port, (PARAM_TRST(cable) << TRST) | UNUSED_BITS ); + parport_set_data( cable->link.port, (PARAM_TRST(cable) << TRST) | UNUSED_BITS ); return PARAM_TRST(cable); } cable_driver_t wiggler2_cable_driver = { "WIGGLER2", N_("Modified (with CPU Reset) WIGGLER JTAG Cable"), - generic_connect, + generic_parport_connect, generic_disconnect, - generic_cable_free, + generic_parport_free, wiggler2_init, - generic_done, + generic_parport_done, generic_set_frequency, wiggler2_clock, wiggler2_get_tdo, @@ -130,5 +131,5 @@ cable_driver_t wiggler2_cable_driver = { wiggler2_set_trst, generic_get_trst, generic_flush_one_by_one, - generic_lptcable_help + generic_parport_help }; diff --git a/jtag/src/tap/cable/xpc.c b/jtag/src/tap/cable/xpc.c index f173d06c..ae12216a 100644 --- a/jtag/src/tap/cable/xpc.c +++ b/jtag/src/tap/cable/xpc.c @@ -1,7 +1,10 @@ /* * $Id: xpc.c,v 1.8 2003/08/19 08:42:20 telka Exp $ * - * Xilinx DLC5 JTAG Parallel Cable III Driver + * Xilinx Platform Cable USB Driver (slow GPIO only) + * Copyright (C) 2008 Kolja Waschk + * + * Loosely based on Xilinx DLC5 JTAG Parallel Cable III Driver * Copyright (C) 2002, 2003 ETC s.r.o. * * This program is free software; you can redistribute it and/or @@ -19,29 +22,165 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * - * Written by Marcel Telka , 2002, 2003. - * - * Documentation: - * [1] Xilinx, Inc., "JTAG Programmer Guide", - * http://toolbox.xilinx.com/docsan/3_1i/pdf/docs/jtg/jtg.pdf - * */ #include "sysdep.h" #include "cable.h" -#include "parport.h" #include "chain.h" #include "generic.h" +#include "generic_usbconn.h" + +#include "usbconn.h" +#include "usbconn/libusb.h" + +/* ----------------------------------------------------------------- */ + +int xpcu_select_gpio(struct usb_dev_handle *xpcu, int int_or_ext ) +{ + if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0052, int_or_ext, NULL, 0, 1000)<0) + { + perror("usb_control_msg(0x52.x) (select gpio)"); + return -1; + } + + return 0; +} + +/* ----------------------------------------------------------------- */ + +int xpcu_request_28(struct usb_dev_handle *xpcu, int value) +{ + /* Maybe clock speed setting? */ + + if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0028, value, NULL, 0, 1000)<0) + { + perror("usb_control_msg(0x28.x)"); + return -1; + } + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +int xpcu_write_gpio(struct usb_dev_handle *xpcu, uint8_t bits) +{ + if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0030, bits, NULL, 0, 1000)<0) + { + perror("usb_control_msg(0x30.0x00) (write port E)"); + return -1; + } + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +int xpcu_read_gpio(struct usb_dev_handle *xpcu, uint8_t *bits) +{ + if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0038, 0, (char*)bits, 1, 1000)<0) + { + perror("usb_control_msg(0x38.0x00) (read port E)"); + return -1; + } + + return 0; +} + +/* ---------------------------------------------------------------------- */ + + +int xpcu_read_cpld_version(struct usb_dev_handle *xpcu, uint16_t *buf) +{ + if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0001, (char*)buf, 2, 1000)<0) + { + perror("usb_control_msg(0x50.1) (read_cpld_version)"); + return -1; + } + return 0; +} + +/* ---------------------------------------------------------------------- */ + +int xpcu_read_firmware_version(struct usb_dev_handle *xpcu, uint16_t *buf) +{ + if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0000, (char*)buf, 2, 1000)<0) + { + perror("usb_control_msg(0x50.0) (read_firmware_version)"); + return -1; + } + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static int +xpcu_common_init( cable_t *cable ) +{ + uint16_t buf; + struct usb_dev_handle *xpcu; + + if (usbconn_open( cable->link.usb )) return -1; + + xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle; + + if(xpcu_request_28(xpcu, 0x11)<0) + { + usb_close(xpcu); + return -1; + }; + + if(xpcu_write_gpio(xpcu, 8)<0) + { + usb_close(xpcu); + return -1; + }; + + /* Read firmware version (constant embedded in firmware) */ + + if(xpcu_read_firmware_version(xpcu, &buf) < 0) + { + usb_close(xpcu); + return -1; + } + else + { + printf("firmware version = 0x%04X (%u)\n", buf, buf); + }; + + /* Read CPLD version (via GPIF) */ + + if(xpcu_read_cpld_version(xpcu, &buf) < 0) + { + usb_close(xpcu); + return -1; + } + else + { + printf("cable CPLD version = 0x%04X (%u)\n", buf, buf); + if(buf == 0) + { + printf("Warning: version '0' can't be correct. Please try resetting the cable\n"); + }; + }; + + PARAM_TRST(cable) = 1; + + return 0; +} static int xpc_int_init( cable_t *cable ) { - if (parport_open( cable->port )) return -1; - if (parport_set_control( cable->port, 1 ) < 0) return -1; + struct usb_dev_handle *xpcu; - PARAM_TRST(cable) = 1; + if (xpcu_common_init( cable )<0) return -1; + + xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle; + if (xpcu_select_gpio(xpcu, 0)<0) return -1; return 0; } @@ -49,14 +188,17 @@ xpc_int_init( cable_t *cable ) static int xpc_ext_init( cable_t *cable ) { - if (parport_open( cable->port )) return -1; - if (parport_set_control( cable->port, 0 ) < 0) return -1; + struct usb_dev_handle *xpcu; - PARAM_TRST(cable) = 1; + if (xpcu_common_init( cable )<0) return -1; + + xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle; + if (xpcu_select_gpio(xpcu, 1)<0) return -1; return 0; } +/* ---------------------------------------------------------------------- */ #define PROG 3 #define TCK 2 @@ -68,81 +210,96 @@ static void xpc_clock( cable_t *cable, int tms, int tdi, int n ) { int i; + struct usb_dev_handle *xpcu; + xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle; - tms = tms ? 1 : 0; - tdi = tdi ? 1 : 0; + tms = tms ? (1<port, (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); - for (i = 0; i < n; i++) { - parport_set_data( cable->port, (1 << PROG) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); - parport_set_data( cable->port, (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + if( xpcu_write_gpio(xpcu, (1<=0) + { + cable_wait( cable ); + for (i = 0; i < n; i++) + { + xpcu_write_gpio(xpcu, (1<port ) >> TDO) & 1; + unsigned char d; + struct usb_dev_handle *xpcu; + xpcu = ((libusb_param_t*)(cable->link.usb->params))->handle; + + xpcu_read_gpio(xpcu, &d); + return (d&(1<frequency = new_frequency; -} - - -void -xpcu_usbcable_help( const char *cablename ) -{ - printf( _( - "Usage: cable %s xpcu VID:PID\n" - "\n" - "VID vendor ID (hex, e.g. 9FB, or empty)\n" - "PID product ID (hex, e.g. 6001, or empty)\n" - "\n" - ), cablename ); -} - cable_driver_t xpc_int_cable_driver = { "xpc_int", N_("Xilinx Platform Cable USB internal chain"), - generic_connect, + generic_usbconn_connect, generic_disconnect, - generic_cable_free, + generic_usbconn_free, xpc_int_init, - generic_done, - xpc_set_frequency, + generic_usbconn_done, + generic_set_frequency, xpc_clock, xpc_get_tdo, generic_transfer, xpc_set_trst, generic_get_trst, generic_flush_using_transfer, - xpcu_usbcable_help + generic_usbconn_help +}; + +usbconn_cable_t usbconn_cable_xpc_int = { + "xpc_int", /* cable name */ + NULL, /* string pattern, not used */ + "libusb", /* usbconn driver */ + 0x03FD, /* VID (Xilinx) */ + 0x0008 /* PID (8) */ }; cable_driver_t xpc_ext_cable_driver = { "xpc_ext", N_("Xilinx Platform Cable USB external chain"), - generic_connect, + generic_usbconn_connect, generic_disconnect, - generic_cable_free, + generic_usbconn_free, xpc_ext_init, - generic_done, - xpc_set_frequency, + generic_usbconn_done, + generic_set_frequency, xpc_clock, xpc_get_tdo, generic_transfer, xpc_set_trst, generic_get_trst, generic_flush_using_transfer, - xpcu_usbcable_help + generic_usbconn_help +}; + +usbconn_cable_t usbconn_cable_xpc_ext = { + "xpc_ext", /* cable name */ + NULL, /* string pattern, not used */ + "libusb", /* usbconn driver */ + 0x03FD, /* VID (Xilinx) */ + 0x0008 /* PID (8) */ }; + diff --git a/jtag/src/tap/parport.c b/jtag/src/tap/parport.c index bcd74401..ecb6f016 100644 --- a/jtag/src/tap/parport.c +++ b/jtag/src/tap/parport.c @@ -40,9 +40,6 @@ extern parport_driver_t ftd2xx_mpsse_parport_driver; extern parport_driver_t ftdi_parport_driver; extern parport_driver_t ftdi_mpsse_parport_driver; #endif /* HAVE_LIBFTDI */ -#ifdef HAVE_LIBUSB -extern parport_driver_t xpcu_pp_driver; -#endif /* HAVE_LIBUSB */ #ifdef HAVE_DEV_PPBUS_PPI_H extern parport_driver_t ppi_parport_driver; #endif /* HAVE_DEV_PPBUS_PPI_H */ @@ -62,9 +59,6 @@ parport_driver_t *parport_drivers[] = { &ftdi_parport_driver, &ftdi_mpsse_parport_driver, #endif /* HAVE_LIBFTDI */ -#ifdef HAVE_LIBUSB - &xpcu_pp_driver, -#endif /* HAVE_LIBUSB */ #ifdef HAVE_DEV_PPBUS_PPI_H &ppi_parport_driver, #endif /* HAVE_DEV_PPBUS_PPI_H */ diff --git a/jtag/src/tap/parport/xpcu_common.c b/jtag/src/tap/parport/xpcu_common.c deleted file mode 100644 index f0afb8bb..00000000 --- a/jtag/src/tap/parport/xpcu_common.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * $Id: ftdi.c,v 1.7 2003/08/19 09:05:25 telka Exp $ - * - * Driver for Xilinx Platform Cable USB - * Copyright (C) 2007 K. Waschk - * - * 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 Kolja Waschk, 2007. - * Structure taken from ppdev.c, written by Marcel Telka, 2003. - * - */ - -#include "sysdep.h" - -#ifdef HAVE_LIBUSB - -#include -#if __CYGWIN__ -#include -#else -#include -#endif -#include -#include -#ifdef HAVE_STROPTS_H -#include -#endif -#include -#include -#include -#include - -/* ---------------------------------------------------------------------- */ - -struct usb_device *find_xpcu(void) -{ - struct usb_device *xpcu_dev = NULL; - - if(usb_find_devices()<0) - { - perror("find_xpcu: usb_find_devices failed"); - } - else - { - struct usb_bus *bus; - - for (bus = usb_busses; bus && !xpcu_dev; bus = bus->next) - { - struct usb_device *dev; - - for (dev = bus->devices; dev && !xpcu_dev; dev = dev->next) - { - if(dev->descriptor.idVendor == 0x3fd) - { - if(dev->descriptor.idProduct == 0x8) - { - xpcu_dev = dev; - } - else - { - fprintf(stderr, - "Found Xilinx device with unknown PID %04X. No firmware loaded?\n", - dev->descriptor.idProduct); - }; - }; - }; - }; - }; - - return xpcu_dev; -} - -/* ---------------------------------------------------------------------- */ - -int xpcu_init() -{ - struct usb_device *xpcu_dev = find_xpcu(); - struct usb_dev_handle *xpcu; - - if(xpcu_dev == NULL) - { - fprintf(stderr, "xpcu_reset: no device found\n"); - return -1; - }; - - xpcu = usb_open(xpcu_dev); - if(xpcu == NULL) - { - perror("xpcu_reset: usb_open() failed"); - return -1; - }; - - if(usb_reset(xpcu) < 0) - { - perror("xpcu_reset: usb_reset() failed"); - return -1; - }; - - return 0; -} - -/* ---------------------------------------------------------------------- */ - -int xpcu_close(struct usb_dev_handle *xpcu) -{ - usb_release_interface(xpcu, 0); - usb_close(xpcu); - - return 0; -} - -/* ---------------------------------------------------------------------- */ - -int xpcu_request_28(struct usb_dev_handle *xpcu, int value) -{ - /* Maybe clock speed setting? */ - - if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0028, value, NULL, 0, 1000)<0) - { - perror("usb_control_msg(0x28.x)"); - return -1; - } - - return 0; -} - -/* ---------------------------------------------------------------------- */ - -int xpcu_write_gpio(struct usb_dev_handle *xpcu, uint8_t bits) -{ - if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0030, bits, NULL, 0, 1000)<0) - { - perror("usb_control_msg(0x30.0x00) (write port E)"); - return -1; - } - - return 0; -} - -/* ---------------------------------------------------------------------- */ - -int xpcu_read_gpio(struct usb_dev_handle *xpcu, uint8_t *bits) -{ - if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0038, 0, (char*)bits, 1, 1000)<0) - { - perror("usb_control_msg(0x38.0x00) (read port E)"); - return -1; - } - - return 0; -} - -/* ---------------------------------------------------------------------- */ - - -int xpcu_read_firmware_version(struct usb_dev_handle *xpcu, uint16_t *buf) -{ - if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0000, (char*)buf, 2, 1000)<0) - { - perror("usb_control_msg(0x50.0) (read_firmware_version)"); - return -1; - } - return 0; -} - -/* ---------------------------------------------------------------------- */ - - -int xpcu_read_cpld_version(struct usb_dev_handle *xpcu, uint16_t *buf) -{ - if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0001, (char*)buf, 2, 1000)<0) - { - perror("usb_control_msg(0x50.1) (read_cpld_version)"); - return -1; - } - return 0; -} - -/* ---------------------------------------------------------------------- */ - - -int xpcu_raise_ioa5(struct usb_dev_handle *xpcu) -{ - if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0018, 0x0000, NULL, 0, 1000)<0) - { - perror("usb_control_msg(0x18.0x00) (raise IOA.5"); - return -1; - } - - return 0; -} - -/* ---------------------------------------------------------------------- */ - - -int xpcu_select_gpio(struct usb_dev_handle *xpcu, int chain) -{ - if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0052, chain, NULL, 0, 1000)<0) - { - perror("usb_control_msg(0x52.x) (select gpio)"); - return -1; - } - - return 0; -} - -/* ---------------------------------------------------------------------- */ - -int xpcu_open(struct usb_dev_handle **xpcu) -{ - uint16_t buf; - struct usb_device *xpcu_dev = find_xpcu(); - - if(xpcu_dev == NULL) - { - fprintf(stderr, "xpcu_open: no device found\n"); - return -1; - }; - - *xpcu = usb_open(xpcu_dev); - if(*xpcu == NULL) - { - perror("xpcu_open: usb_open() failed"); - return -1; - }; - - if(usb_claim_interface(*xpcu, 0) != 0) - { - perror("xpcu_open: usb_claim_interface failed"); - usb_close(*xpcu); - return -1; - }; - - - if(xpcu_request_28(*xpcu, 0x11)<0) - { - usb_close(*xpcu); - return -1; - }; - - if(xpcu_write_gpio(*xpcu, 8)<0) - { - usb_close(*xpcu); - return -1; - }; - - /* Read firmware version (constant embedded in firmware) */ - - if(xpcu_read_firmware_version(*xpcu, &buf) < 0) - { - usb_close(*xpcu); - return -1; - } - else - { - printf("firmware version = 0x%04X (%u)\n", buf, buf); - }; - - /* Read CPLD version (via GPIF) */ - - if(xpcu_read_cpld_version(*xpcu, &buf) < 0) - { - usb_close(*xpcu); - return -1; - } - else - { - printf("cable CPLD version = 0x%04X (%u)\n", buf, buf); - if(buf == 0) - { - printf("Warning: version '0' can't be correct. Please try resetting the cable\n"); - }; - }; - - return 0; -} - -#endif /* HAVE_LIBUSB */ diff --git a/jtag/src/tap/parport/xpcu_pp.c b/jtag/src/tap/parport/xpcu_pp.c deleted file mode 100644 index c4ac56df..00000000 --- a/jtag/src/tap/parport/xpcu_pp.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * $Id: ftdi.c,v 1.7 2003/08/19 09:05:25 telka Exp $ - * - * Driver for Xilinx Platform Cable USB - * Copyright (C) 2007 K. Waschk - * - * 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 Kolja Waschk, 2007. - * Structure taken from ppdev.c, written by Marcel Telka, 2003. - * - */ - -#include "sysdep.h" - -#ifdef HAVE_LIBUSB - -#include -#if __CYGWIN__ -#include -#else -#include -#endif -#include -#include -#ifdef HAVE_STROPTS_H -#include -#endif -#include -#include -#include -#include - -#include "parport.h" -#include "cable.h" - -#include "xpcu.h" - -typedef struct { - char *serial; - unsigned int vendor_id; - unsigned int product_id; - usb_dev_handle *dev; -} xpcu_params_t; - -parport_driver_t xpcu_pp_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; /* devices */ - -/* ---------------------------------------------------------------------- */ - -static parport_t * -xpcu_pp_alloc( const char *vidpid ) -{ - xpcu_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->product_id = 0; - params->vendor_id = 0; - params->serial = NULL; - params->dev = NULL; - - { - char *f = strchr(vidpid, ':'); - char *l = strrchr(vidpid, ':'); - if(f) - { - params->vendor_id = strtoul(vidpid, NULL, 16); - params->product_id = strtoul(f+1, NULL, 16); - if(l!=f) params->serial = strdup(l+1); - }; - }; - - parport->params = params; - parport->driver = &xpcu_pp_driver; - parport->cable = NULL; - - node->port = parport; - node->next = ports; - - ports = node; - - return parport; -} - -/* ---------------------------------------------------------------------- */ - -static void -xpcu_pp_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( ((xpcu_params_t *) port->params)->serial ); - free( port->params ); - free( port ); -} - -/* ---------------------------------------------------------------------- */ - -parport_t * -xpcu_pp_connect( const char **par, int parnum ) -{ - port_node_t *pn; - parport_t *parport; - - - if (parnum != 1) { - printf( _("Syntax error!\n") ); - return NULL; - } - - for (pn = ports; pn; pn = pn->next) - if (strcmp( pn->port->params, par[0] ) == 0) { - printf( _("Disconnecting %s, device %s\n"), _(pn->port->cable->driver->description), par[0] ); - pn->port->cable->driver->disconnect( pn->port->cable ); - break; - } - -#ifdef TODO - printf( _("Initializing %s, device %s\n"), _(cable_drivers[i]->description), par[0] ); -#else - printf( _("Initializing device %s\n"), par[0] ); -#endif - - parport = xpcu_pp_alloc( par[0] ); - if (!parport) { - printf( _("%s(%d) Out of memory.\n"), __FILE__, __LINE__ ); - return NULL; - } - - return parport; -} - -/* ---------------------------------------------------------------------- */ - -static int -xpcu_pp_open( parport_t *parport ) -{ - xpcu_params_t *p = parport->params; - - usb_init(); - - if(usb_find_busses()<0) - { - perror("usb_find_busses failed"); - return -1; - }; - - if(xpcu_init() < 0) - { - fprintf (stderr, "can't initialize XPCU\n"); - return -1; - }; - - if(xpcu_open(&(p->dev)) < 0) - { - fprintf (stderr, "can't open XPCU\n"); - return -1; - }; - - if(xpcu_raise_ioa5(p->dev)<0) return -1; - - /* access external chain by default */ - if(xpcu_select_gpio(p->dev, 0)<0) return -1; - - return 0; -} - -/* ---------------------------------------------------------------------- */ - -static int -xpcu_pp_close( parport_t *parport ) -{ - xpcu_params_t *p = parport->params; - xpcu_close(p->dev); - return 0; -} - -/* ---------------------------------------------------------------------- */ - -static int -xpcu_pp_set_data( parport_t *parport, uint8_t data ) -{ - xpcu_params_t *p = parport->params; - - if(xpcu_write_gpio(p->dev, data) < 0) return -1; - return 0; -} - -/* ---------------------------------------------------------------------- */ - -static int -xpcu_pp_get_data( parport_t *parport ) -{ - unsigned char d; - xpcu_params_t *p = parport->params; - - if(xpcu_read_gpio(p->dev, &d) < 0) return 0; - return d; -} - -/* ---------------------------------------------------------------------- */ - -static int -xpcu_pp_get_status( parport_t *parport ) -{ - return 0; -} - -/* ---------------------------------------------------------------------- */ - -static int -xpcu_pp_set_control( parport_t *parport, uint8_t data ) -{ - xpcu_params_t *p = parport->params; - - if(xpcu_select_gpio(p->dev, data)<0) return -1; - return 0; -} - -/* ---------------------------------------------------------------------- */ - -parport_driver_t xpcu_pp_driver = { - "xpcu", - xpcu_pp_connect, - xpcu_pp_free, - xpcu_pp_open, - xpcu_pp_close, - xpcu_pp_set_data, - xpcu_pp_get_data, - xpcu_pp_get_status, - xpcu_pp_set_control -}; - -#endif /* HAVE_LIBUSB */ diff --git a/jtag/src/tap/usbconn.c b/jtag/src/tap/usbconn.c new file mode 100644 index 00000000..b629cfcf --- /dev/null +++ b/jtag/src/tap/usbconn.c @@ -0,0 +1,52 @@ +/* + * $Id: usbconn.c 851 2007-12-15 22:53:24Z kawk $ + * + * Copyright (C) 2008 K. Waschk + * + * 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 Kolja Waschk , 2008 + * + */ + +#include "sysdep.h" + +#include + +#include "usbconn.h" + +#ifdef HAVE_LIBUSB +extern usbconn_driver_t usbconn_libusb_driver; +#endif /* HAVE_LIBUSB */ + +usbconn_driver_t *usbconn_drivers[] = { +#ifdef HAVE_LIBUSB + &usbconn_libusb_driver, +#endif /* HAVE_LIBUSB */ + NULL /* last must be NULL */ +}; + +int +usbconn_open( usbconn_t *conn ) +{ + return conn->driver->open( conn ); +} + +int +usbconn_close( usbconn_t *conn ) +{ + return conn->driver->close( conn ); +} diff --git a/jtag/src/tap/usbconn/libusb.c b/jtag/src/tap/usbconn/libusb.c new file mode 100644 index 00000000..45216960 --- /dev/null +++ b/jtag/src/tap/usbconn/libusb.c @@ -0,0 +1,243 @@ +/* + * $Id: ftdi.c,v 1.7 2003/08/19 09:05:25 telka Exp $ + * + * Link driver for accessing USB devices via libusb + * + * Copyright (C) 2008 K. Waschk + * + * 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 Kolja Waschk, 2008 + * + */ + +#include "sysdep.h" + +#ifdef HAVE_LIBUSB + +#include +#if __CYGWIN__ +#include +#else +#include +#endif +#include +#include +#ifdef HAVE_STROPTS_H +#include +#endif +#include +#include +#include +#include + +#include "parport.h" +#include "cable.h" +#include "usbconn.h" + +typedef struct { + struct usb_device *dev; + struct usb_dev_handle *handle; +} libusb_param_t; + +usbconn_driver_t usbconn_libusb_driver; + +/* ---------------------------------------------------------------------- */ + +static int +libusb_match_desc(struct usb_device *dev, char *desc) +{ + int r = 0; + char buf[256]; + usb_dev_handle *handle; + + if(desc == NULL) return 1; + + handle = usb_open(dev); + if(handle == NULL) + { + perror("libusb: usb_open() failed"); + return 0; + } + if(dev->descriptor.iManufacturer) + { + r = usb_get_string_simple(handle, dev->descriptor.iManufacturer, buf, sizeof(buf)); + if(r > 0) + { + if(strstr(buf, desc) == NULL) r = 0; + } + } + if(r <= 0 && dev->descriptor.iProduct) + { + r = usb_get_string_simple(handle, dev->descriptor.iProduct, buf, sizeof(buf)); + if(r > 0) + { + if(strstr(buf, desc) == NULL) r = 0; + } + } + if(r <= 0 && dev->descriptor.iSerialNumber) + { + r = usb_get_string_simple(handle, dev->descriptor.iSerialNumber, buf, sizeof(buf)); + if(r > 0) + { + if(strstr(buf, desc) == NULL) r = 0; + } + } + usb_close(handle); + return r > 0 ? 1 : 0; +} + + +/* ---------------------------------------------------------------------- */ + +usbconn_t * +usbconn_libusb_connect( const char **param, int paramc, usbconn_cable_t *template ) +{ + struct usb_bus *bus; + struct usb_device *found_dev = NULL; + usbconn_t *libusb_conn; + libusb_param_t *libusb_params; + + usb_init(); + if(usb_find_busses()<0) + { + perror("libusb: usb_find_busses failed"); + return NULL; + } + if(usb_find_devices()<0) + { + perror("libusb: usb_find_devices failed"); + return NULL; + } + + for (bus = usb_busses; bus && !found_dev; bus = bus->next) + { + struct usb_device *dev; + + for (dev = bus->devices; dev && !found_dev; dev = dev->next) + { + if(((template->vid<0)||(dev->descriptor.idVendor == template->vid)) + &&((template->pid<0)||(dev->descriptor.idProduct == template->pid))) + { + if(libusb_match_desc(dev, template->desc)) + { + found_dev = dev; + } + } + } + } + + if(!found_dev) + { + return NULL; + } + + libusb_conn = malloc( sizeof(usbconn_t) ); + libusb_params = malloc(sizeof(libusb_param_t)); + if(libusb_params == NULL || libusb_conn == NULL) + { + printf(_("Out of memory\n")); + free(libusb_params); + free(libusb_conn); + return NULL; + }; + + libusb_params->dev = found_dev; + libusb_params->handle = NULL; + libusb_conn->params = libusb_params; + libusb_conn->driver = &usbconn_libusb_driver; + libusb_conn->cable = NULL; + + return libusb_conn; +} + + +/* ---------------------------------------------------------------------- */ + +static int +usbconn_libusb_open( usbconn_t *conn ) +{ + libusb_param_t *p = conn->params; + + p->handle = usb_open(p->dev); + if(p->handle == NULL) + { + perror("libusb: usb_open() failed"); + } + else + { +#if 1 + usb_set_configuration(p->handle, + p->dev->config[0].bConfigurationValue); +#endif + if(usb_claim_interface(p->handle, 0) != 0) + { + perror("libusb: usb_claim_interface failed"); + usb_close(p->handle); + p->handle = NULL; + } +#if 1 + else + { + usb_set_altinterface(p->handle, 0); + } +#endif + } + + if(p->handle == NULL) + { + /* TODO: disconnect? */ + return -1; + } + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static int +usbconn_libusb_close( usbconn_t *conn ) +{ + libusb_param_t *p = conn->params; + if(p->handle != NULL) + { + usb_release_interface(p->handle, 0); + usb_close(p->handle); + } + p->handle = NULL; + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static void +usbconn_libusb_free( usbconn_t *conn ) +{ + free( conn->params ); + free( conn ); +} + +/* ---------------------------------------------------------------------- */ + +usbconn_driver_t usbconn_libusb_driver = { + "libusb", + usbconn_libusb_connect, + usbconn_libusb_free, + usbconn_libusb_open, + usbconn_libusb_close +}; + +#endif /* HAVE_LIBUSB */