diff --git a/jtag/configure.ac b/jtag/configure.ac index 612f64a0..5c4d7549 100644 --- a/jtag/configure.ac +++ b/jtag/configure.ac @@ -98,6 +98,30 @@ AC_CHECK_HEADERS(linux/ppdev.h) VL_LIB_READLINE +dnl check for libftdi-config +AC_PATH_PROG(HAVELIBFTDI, libftdi-config, $PATH) +if test ! -z "$HAVELIBFTDI"; then +dnl LIBFTDI_CFLAGS=`$HAVELIBFTDI --cflags` + LIBFTDI_LIBS=`$HAVELIBFTDI --libs` + CFLAGS="$CFLAGS $LIBFTDI_CFLAGS" + LIBS="$LIBS $LIBFTDI_LIBS" + AC_DEFINE(HAVE_LIBFTDI, 1, [Define if you have libftdi]) +else + AC_MSG_ERROR([*** libftdi-config not found. You need a working libftdi installation.]) +fi + +dnl check for libusb-config +AC_PATH_PROG(HAVELIBUSB, libusb-config, $PATH) +if test ! -z "$HAVELIBUSB"; then +dnl LIBUSB_CFLAGS=`$HAVELIBUSB --cflags` + LIBUSB_LIBS=`$HAVELIBUSB --libs` + CFLAGS="$CFLAGS $LIBUSB_CFLAGS" + LIBS="$LIBS $LIBUSB_LIBS" + AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb]) +else + AC_MSG_ERROR([*** libusb-config not found. You need a working libusb installation.]) +fi + CFLAGS="$CFLAGS -Wall" CPPFLAGS="$CPPFLAGS -I\$(top_srcdir) -I\$(top_srcdir)/include" diff --git a/jtag/data/Makefile.am b/jtag/data/Makefile.am index 676ae9c0..a04ad694 100644 --- a/jtag/data/Makefile.am +++ b/jtag/data/Makefile.am @@ -126,6 +126,10 @@ nobase_dist_pkgdata_DATA = \ xilinx/xc18v04pc44/STEPPINGS \ xilinx/xc2c256-tq144/STEPPINGS \ xilinx/xc2c256-tq144/xc2c256-tq144 \ + xilinx/xc2c256-vq100/STEPPINGS \ + xilinx/xc2c256-vq100/xc2c256-vq100 \ + xilinx/xc2c64a-vq44/STEPPINGS \ + xilinx/xc2c64a-vq44/xc2c64a-vq44 \ xilinx/xc2s200e-pq208/STEPPINGS \ xilinx/xc2s200e-pq208/xc2s200e-pq208 \ xilinx/xc2s300e/STEPPINGS \ diff --git a/jtag/data/xilinx/PARTS b/jtag/data/xilinx/PARTS index 7f9c8e37..83bba113 100644 --- a/jtag/data/xilinx/PARTS +++ b/jtag/data/xilinx/PARTS @@ -27,7 +27,9 @@ 0100100010001011 . XCR3128XL-TQ144 0100100010001100 xcr3128xl-cs144 XCR3128XL-CS144 0100100101001110 xcr3256xl-ft256 XCR3256XL-FT256 +0110110101001010 xc2c256-vq100 XC2C256-VQ100 0110110101001100 xc2c256-tq144 XC2C256-TQ144 +0110111001011110 xc2c64a-vq44 XC2C64-VQ44 0000101000100000 xc2s300e XC2S300E 0001010000001101 xc3s50 xc3s50 0001010000010100 xc3s200 xc3s200 diff --git a/jtag/data/xilinx/xc2c256-vq100/STEPPINGS b/jtag/data/xilinx/xc2c256-vq100/STEPPINGS new file mode 100644 index 00000000..2017c39f --- /dev/null +++ b/jtag/data/xilinx/xc2c256-vq100/STEPPINGS @@ -0,0 +1,26 @@ +# +# $Id: STEPPINGS,v 1.1 2003/02/14 11:14:56 telka Exp $ +# +# Copyright (C) 2003 Tower Technologies s.r.l. +# +# 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, ixo.de, 2007 +# + +# bits 31-28 of the Device Identification Register +0000 xc2c256-vq100 0 +0001 xc2c256-vq100 1 diff --git a/jtag/data/xilinx/xc2c256-vq100/xc2c256-vq100 b/jtag/data/xilinx/xc2c256-vq100/xc2c256-vq100 new file mode 100644 index 00000000..86a1f495 --- /dev/null +++ b/jtag/data/xilinx/xc2c256-vq100/xc2c256-vq100 @@ -0,0 +1,727 @@ +# +# $Id: xc2c256-tq144,v 1.2 2003/08/13 09:24:36 telka Exp $ +# +# JTAG declarations for XC2C256-VQ100 +# +# Based on the declarations for XC2C256-TQ144, +# Written by Alessandro Zummo , 2003. +# Copyright (C) 2003 Tower Technologies s.r.l., +# and bsdl2jtag output with Xilinx file [2] as input. +# +# 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. +# +# Documentation: +# [1] Xilinx Inc., "CoolRunner-II CPLD Family Advance Product Specification", +# DS090 (v1.3) September 24, 2002 +# [2] Xilinx Inc., "BSDL file for device XC2C256, package VQ144 +# Revision: 1.11", 2006-10-17 +# [3] Xilinx Inc., "XC2C256 CoolRunner-II CPLD Advance Product Specification", +# DS094 (v1.2) November 20, 2002 + +# mandatory data registers +register BSR 552 # see [2] +register BR 1 + +# optional data registers +register DIR 32 + +# user-defined registers +register ISPSR 274 # ISP (In-System Programming) Shift Register, see [2] + +# instructions - see [2] +instruction length 8 + +# mandatory instructions - see [2] +instruction EXTEST 00000000 BSR +instruction SAMPLE/PRELOAD 00000011 BSR +instruction BYPASS 11111111 BR +instruction INTEST 00000010 BSR +instruction IDCODE 00000001 DIR +instruction USERCODE 11111101 DIR +instruction HIGHZ 11111100 BR +instruction CLAMP 11111010 BR + +# user-defined instructions - see [2] +instruction ISC_ENABLE_CLAMP 11101001 BR +instruction ISC_ENABLEOTF 11100100 ISPSR +instruction ISC_ENABLE 11101000 ISPSR +instruction ISC_SRAM_READ 11100111 ISPSR +instruction ISC_SRAM_WRITE 11100110 ISPSR +instruction ISC_ERASE 11101101 ISPSR +instruction ISC_PROGRAM 11101010 ISPSR +instruction ISC_READ 11101110 ISPSR +instruction ISC_INIT 11110000 ISPSR +instruction ISC_DISABLE 11000000 ISPSR +instruction TEST_ENABLE 00010001 ISPSR +instruction BULKPROG 00010010 ISPSR +instruction ERASE_ALL 00010100 ISPSR +instruction MVERIFY 00010011 ISPSR +instruction TEST_DISABLE 00010101 ISPSR +instruction ISC_NOOP 11100000 BR + +# signals - derived from [2] using bsdl2jtag +signal tdi +signal tck +signal tms +signal tdo +signal IO_2 +signal IO_5 +signal IO_6 +signal IO_7 +signal IO_8 +signal IO_11 +signal IO_13 +signal IO_15 +signal IO_17 +signal IO_19 +signal IO_20 +signal IO_26 +signal IO_28 +signal IO_30 +signal IO_32 +signal IO_33 +signal IO_34 +signal IO_35 +signal IO_37 +signal IO_38 +signal IO_40 +signal IO_47 +signal IO_49 +signal IO_56 +signal IO_58 +signal IO_61 +signal IO_63 +signal IO_65 +signal IO_70 +signal IO_71 +signal IO_72 +signal IO_73 +signal IO_74 +signal IO_75 +signal IO_83 +signal IO_84 +signal IO_85 +signal IO_86 +signal IO_87 +signal IO_88 +signal IO_90 +signal IO_91 +signal IO_93 +signal IO_95 +signal IO_97 +signal IO_102 +signal IO_103 +signal IO_104 +signal IO_105 +signal IO_106 +signal IO_107 +signal IO_109 +signal IO_120 +signal IO_121 +signal IO_122 +signal IO_123 +signal IO_132 +signal IO_134 +signal IO_135 +signal IO_136 +signal IO_139 +signal IO_141 +signal IO_143 +signal IO_145 +signal IO_149 +signal IO_151 +signal IO_153 +signal IO_157 +signal IO_158 +signal IO_166 +signal IO_167 +signal IO_168 +signal IO_169 +signal IO_170 +signal IO_171 +signal IO_176 +signal IO_177 +signal IO_178 +signal IO_179 +signal IO_180 +signal vdd1 +signal vdd2 +signal vdd3 +signal vdd4 +signal vdd5 +signal vdd6 +signal vdd7 +signal gnd1 +signal gnd2 +signal gnd3 +signal gnd4 +signal gnd5 +signal gnd6 +signal gnd7 + +# bits - derived from [2] using bsdl2jtag +bit 551 O 1 * +bit 550 O 1 * +bit 549 O 1 * +bit 548 O 1 * +bit 547 O 1 * +bit 546 O 1 * +bit 545 I 1 IO_2 +bit 544 O 1 IO_2 543 0 Z +bit 543 C 0 * +bit 542 O 1 * +bit 541 O 1 * +bit 540 O 1 * +bit 539 O 1 * +bit 538 O 1 * +bit 537 O 1 * +bit 536 I 1 IO_5 +bit 535 O 1 IO_5 534 0 Z +bit 534 C 0 * +bit 533 I 1 IO_6 +bit 532 O 1 IO_6 531 0 Z +bit 531 C 0 * +bit 530 I 1 IO_7 +bit 529 O 1 IO_7 528 0 Z +bit 528 C 0 * +bit 527 I 1 IO_8 +bit 526 O 1 IO_8 525 0 Z +bit 525 C 0 * +bit 524 O 1 * +bit 523 O 1 * +bit 522 O 1 * +bit 521 O 1 * +bit 520 O 1 * +bit 519 O 1 * +bit 518 O 1 * +bit 517 O 1 * +bit 516 O 1 * +bit 515 O 1 * +bit 514 O 1 * +bit 513 O 1 * +bit 512 O 1 * +bit 511 O 1 * +bit 510 O 1 * +bit 509 O 1 * +bit 508 O 1 * +bit 507 O 1 * +bit 506 I 1 IO_26 +bit 505 O 1 IO_26 504 0 Z +bit 504 C 0 * +bit 503 O 1 * +bit 502 O 1 * +bit 501 O 1 * +bit 500 I 1 IO_28 +bit 499 O 1 IO_28 498 0 Z +bit 498 C 0 * +bit 497 O 1 * +bit 496 O 1 * +bit 495 O 1 * +bit 494 I 1 IO_30 +bit 493 O 1 IO_30 492 0 Z +bit 492 C 0 * +bit 491 O 1 * +bit 490 O 1 * +bit 489 O 1 * +bit 488 I 1 IO_32 +bit 487 O 1 IO_32 486 0 Z +bit 486 C 0 * +bit 485 I 1 IO_11 +bit 484 O 1 IO_11 483 0 Z +bit 483 C 0 * +bit 482 O 1 * +bit 481 O 1 * +bit 480 O 1 * +bit 479 I 1 IO_13 +bit 478 O 1 IO_13 477 0 Z +bit 477 C 0 * +bit 476 O 1 * +bit 475 O 1 * +bit 474 O 1 * +bit 473 I 1 IO_15 +bit 472 O 1 IO_15 471 0 Z +bit 471 C 0 * +bit 470 O 1 * +bit 469 O 1 * +bit 468 O 1 * +bit 467 I 1 IO_17 +bit 466 O 1 IO_17 465 0 Z +bit 465 C 0 * +bit 464 O 1 * +bit 463 O 1 * +bit 462 O 1 * +bit 461 I 1 IO_19 +bit 460 O 1 IO_19 459 0 Z +bit 459 C 0 * +bit 458 I 1 IO_20 +bit 457 O 1 IO_20 456 0 Z +bit 456 C 0 * +bit 455 O 1 * +bit 454 O 1 * +bit 453 O 1 * +bit 452 I 1 IO_33 +bit 451 O 1 IO_33 450 0 Z +bit 450 C 0 * +bit 449 I 1 IO_34 +bit 448 O 1 IO_34 447 0 Z +bit 447 C 0 * +bit 446 I 1 IO_35 +bit 445 O 1 IO_35 444 0 Z +bit 444 C 0 * +bit 443 O 1 * +bit 442 O 1 * +bit 441 O 1 * +bit 440 I 1 IO_37 +bit 439 O 1 IO_37 438 0 Z +bit 438 C 0 * +bit 437 I 1 IO_38 +bit 436 O 1 IO_38 435 0 Z +bit 435 C 0 * +bit 434 O 1 * +bit 433 O 1 * +bit 432 O 1 * +bit 431 I 1 IO_40 +bit 430 O 1 IO_40 429 0 Z +bit 429 C 0 * +bit 428 O 1 * +bit 427 O 1 * +bit 426 O 1 * +bit 425 O 1 * +bit 424 O 1 * +bit 423 O 1 * +bit 422 O 1 * +bit 421 O 1 * +bit 420 O 1 * +bit 419 O 1 * +bit 418 O 1 * +bit 417 O 1 * +bit 416 O 1 * +bit 415 O 1 * +bit 414 O 1 * +bit 413 O 1 * +bit 412 O 1 * +bit 411 O 1 * +bit 410 I 1 IO_47 +bit 409 O 1 IO_47 408 0 Z +bit 408 C 0 * +bit 407 O 1 * +bit 406 O 1 * +bit 405 O 1 * +bit 404 I 1 IO_49 +bit 403 O 1 IO_49 402 0 Z +bit 402 C 0 * +bit 401 O 1 * +bit 400 O 1 * +bit 399 O 1 * +bit 398 O 1 * +bit 397 O 1 * +bit 396 O 1 * +bit 395 O 1 * +bit 394 O 1 * +bit 393 O 1 * +bit 392 O 1 * +bit 391 O 1 * +bit 390 O 1 * +bit 389 O 1 * +bit 388 O 1 * +bit 387 O 1 * +bit 386 O 1 * +bit 385 O 1 * +bit 384 O 1 * +bit 383 O 1 * +bit 382 O 1 * +bit 381 O 1 * +bit 380 O 1 * +bit 379 O 1 * +bit 378 O 1 * +bit 377 O 1 * +bit 376 O 1 * +bit 375 O 1 * +bit 374 I 1 IO_70 +bit 373 O 1 IO_70 372 0 Z +bit 372 C 0 * +bit 371 I 1 IO_71 +bit 370 O 1 IO_71 369 0 Z +bit 369 C 0 * +bit 368 I 1 IO_72 +bit 367 O 1 IO_72 366 0 Z +bit 366 C 0 * +bit 365 I 1 IO_73 +bit 364 O 1 IO_73 363 0 Z +bit 363 C 0 * +bit 362 I 1 IO_74 +bit 361 O 1 IO_74 360 0 Z +bit 360 C 0 * +bit 359 I 1 IO_75 +bit 358 O 1 IO_75 357 0 Z +bit 357 C 0 * +bit 356 O 1 * +bit 355 O 1 * +bit 354 O 1 * +bit 353 O 1 * +bit 352 O 1 * +bit 351 O 1 * +bit 350 O 1 * +bit 349 O 1 * +bit 348 O 1 * +bit 347 I 1 IO_56 +bit 346 O 1 IO_56 345 0 Z +bit 345 C 0 * +bit 344 O 1 * +bit 343 O 1 * +bit 342 O 1 * +bit 341 I 1 IO_58 +bit 340 O 1 IO_58 339 0 Z +bit 339 C 0 * +bit 338 O 1 * +bit 337 O 1 * +bit 336 O 1 * +bit 335 O 1 * +bit 334 O 1 * +bit 333 O 1 * +bit 332 I 1 IO_61 +bit 331 O 1 IO_61 330 0 Z +bit 330 C 0 * +bit 329 O 1 * +bit 328 O 1 * +bit 327 O 1 * +bit 326 I 1 IO_63 +bit 325 O 1 IO_63 324 0 Z +bit 324 C 0 * +bit 323 O 1 * +bit 322 O 1 * +bit 321 O 1 * +bit 320 I 1 IO_65 +bit 319 O 1 IO_65 318 0 Z +bit 318 C 0 * +bit 317 O 1 * +bit 316 O 1 * +bit 315 O 1 * +bit 314 O 1 * +bit 313 O 1 * +bit 312 O 1 * +bit 311 O 1 * +bit 310 O 1 * +bit 309 O 1 * +bit 308 O 1 * +bit 307 O 1 * +bit 306 O 1 * +bit 305 O 1 * +bit 304 O 1 * +bit 303 O 1 * +bit 302 I 1 IO_83 +bit 301 O 1 IO_83 300 0 Z +bit 300 C 0 * +bit 299 I 1 IO_84 +bit 298 O 1 IO_84 297 0 Z +bit 297 C 0 * +bit 296 I 1 IO_85 +bit 295 O 1 IO_85 294 0 Z +bit 294 C 0 * +bit 293 I 1 IO_86 +bit 292 O 1 IO_86 291 0 Z +bit 291 C 0 * +bit 290 I 1 IO_87 +bit 289 O 1 IO_87 288 0 Z +bit 288 C 0 * +bit 287 I 1 IO_88 +bit 286 O 1 IO_88 285 0 Z +bit 285 C 0 * +bit 284 O 1 * +bit 283 O 1 * +bit 282 O 1 * +bit 281 I 1 IO_90 +bit 280 O 1 IO_90 279 0 Z +bit 279 C 0 * +bit 278 I 1 IO_91 +bit 277 O 1 IO_91 276 0 Z +bit 276 C 0 * +bit 275 O 1 * +bit 274 O 1 * +bit 273 O 1 * +bit 272 I 1 IO_93 +bit 271 O 1 IO_93 270 0 Z +bit 270 C 0 * +bit 269 O 1 * +bit 268 O 1 * +bit 267 O 1 * +bit 266 I 1 IO_95 +bit 265 O 1 IO_95 264 0 Z +bit 264 C 0 * +bit 263 O 1 * +bit 262 O 1 * +bit 261 O 1 * +bit 260 I 1 IO_97 +bit 259 O 1 IO_97 258 0 Z +bit 258 C 0 * +bit 257 O 1 * +bit 256 O 1 * +bit 255 O 1 * +bit 254 O 1 * +bit 253 O 1 * +bit 252 O 1 * +bit 251 O 1 * +bit 250 O 1 * +bit 249 O 1 * +bit 248 O 1 * +bit 247 O 1 * +bit 246 O 1 * +bit 245 O 1 * +bit 244 O 1 * +bit 243 O 1 * +bit 242 O 1 * +bit 241 O 1 * +bit 240 O 1 * +bit 239 O 1 * +bit 238 O 1 * +bit 237 O 1 * +bit 236 O 1 * +bit 235 O 1 * +bit 234 O 1 * +bit 233 O 1 * +bit 232 O 1 * +bit 231 O 1 * +bit 230 O 1 * +bit 229 O 1 * +bit 228 O 1 * +bit 227 I 1 IO_120 +bit 226 O 1 IO_120 225 0 Z +bit 225 C 0 * +bit 224 I 1 IO_121 +bit 223 O 1 IO_121 222 0 Z +bit 222 C 0 * +bit 221 I 1 IO_122 +bit 220 O 1 IO_122 219 0 Z +bit 219 C 0 * +bit 218 I 1 IO_123 +bit 217 O 1 IO_123 216 0 Z +bit 216 C 0 * +bit 215 O 1 * +bit 214 O 1 * +bit 213 O 1 * +bit 212 O 1 * +bit 211 O 1 * +bit 210 O 1 * +bit 209 I 1 IO_102 +bit 208 O 1 IO_102 207 0 Z +bit 207 C 0 * +bit 206 I 1 IO_103 +bit 205 O 1 IO_103 204 0 Z +bit 204 C 0 * +bit 203 I 1 IO_104 +bit 202 O 1 IO_104 201 0 Z +bit 201 C 0 * +bit 200 I 1 IO_105 +bit 199 O 1 IO_105 198 0 Z +bit 198 C 0 * +bit 197 I 1 IO_106 +bit 196 O 1 IO_106 195 0 Z +bit 195 C 0 * +bit 194 I 1 IO_107 +bit 193 O 1 IO_107 192 0 Z +bit 192 C 0 * +bit 191 O 1 * +bit 190 O 1 * +bit 189 O 1 * +bit 188 I 1 IO_109 +bit 187 O 1 IO_109 186 0 Z +bit 186 C 0 * +bit 185 O 1 * +bit 184 O 1 * +bit 183 O 1 * +bit 182 O 1 * +bit 181 O 1 * +bit 180 O 1 * +bit 179 O 1 * +bit 178 O 1 * +bit 177 O 1 * +bit 176 O 1 * +bit 175 O 1 * +bit 174 O 1 * +bit 173 O 1 * +bit 172 O 1 * +bit 171 O 1 * +bit 170 O 1 * +bit 169 O 1 * +bit 168 O 1 * +bit 167 O 1 * +bit 166 O 1 * +bit 165 O 1 * +bit 164 O 1 * +bit 163 O 1 * +bit 162 O 1 * +bit 161 O 1 * +bit 160 O 1 * +bit 159 O 1 * +bit 158 O 1 * +bit 157 O 1 * +bit 156 O 1 * +bit 155 I 1 IO_132 +bit 154 O 1 IO_132 153 0 Z +bit 153 C 0 * +bit 152 O 1 * +bit 151 O 1 * +bit 150 O 1 * +bit 149 I 1 IO_134 +bit 148 O 1 IO_134 147 0 Z +bit 147 C 0 * +bit 146 I 1 IO_135 +bit 145 O 1 IO_135 144 0 Z +bit 144 C 0 * +bit 143 I 1 IO_136 +bit 142 O 1 IO_136 141 0 Z +bit 141 C 0 * +bit 140 O 1 * +bit 139 O 1 * +bit 138 O 1 * +bit 137 O 1 * +bit 136 O 1 * +bit 135 O 1 * +bit 134 I 1 IO_139 +bit 133 O 1 IO_139 132 0 Z +bit 132 C 0 * +bit 131 O 1 * +bit 130 O 1 * +bit 129 O 1 * +bit 128 I 1 IO_141 +bit 127 O 1 IO_141 126 0 Z +bit 126 C 0 * +bit 125 O 1 * +bit 124 O 1 * +bit 123 O 1 * +bit 122 I 1 IO_143 +bit 121 O 1 IO_143 120 0 Z +bit 120 C 0 * +bit 119 O 1 * +bit 118 O 1 * +bit 117 O 1 * +bit 116 I 1 IO_145 +bit 115 O 1 IO_145 114 0 Z +bit 114 C 0 * +bit 113 O 1 * +bit 112 O 1 * +bit 111 O 1 * +bit 110 O 1 * +bit 109 O 1 * +bit 108 O 1 * +bit 107 O 1 * +bit 106 O 1 * +bit 105 O 1 * +bit 104 O 1 * +bit 103 O 1 * +bit 102 O 1 * +bit 101 O 1 * +bit 100 O 1 * +bit 99 O 1 * +bit 98 O 1 * +bit 97 O 1 * +bit 96 O 1 * +bit 95 O 1 * +bit 94 O 1 * +bit 93 O 1 * +bit 92 O 1 * +bit 91 O 1 * +bit 90 O 1 * +bit 89 O 1 * +bit 88 O 1 * +bit 87 O 1 * +bit 86 I 1 IO_166 +bit 85 O 1 IO_166 84 0 Z +bit 84 C 0 * +bit 83 I 1 IO_167 +bit 82 O 1 IO_167 81 0 Z +bit 81 C 0 * +bit 80 I 1 IO_168 +bit 79 O 1 IO_168 78 0 Z +bit 78 C 0 * +bit 77 I 1 IO_169 +bit 76 O 1 IO_169 75 0 Z +bit 75 C 0 * +bit 74 I 1 IO_170 +bit 73 O 1 IO_170 72 0 Z +bit 72 C 0 * +bit 71 I 1 IO_171 +bit 70 O 1 IO_171 69 0 Z +bit 69 C 0 * +bit 68 I 1 IO_149 +bit 67 O 1 IO_149 66 0 Z +bit 66 C 0 * +bit 65 O 1 * +bit 64 O 1 * +bit 63 O 1 * +bit 62 I 1 IO_151 +bit 61 O 1 IO_151 60 0 Z +bit 60 C 0 * +bit 59 O 1 * +bit 58 O 1 * +bit 57 O 1 * +bit 56 I 1 IO_153 +bit 55 O 1 IO_153 54 0 Z +bit 54 C 0 * +bit 53 O 1 * +bit 52 O 1 * +bit 51 O 1 * +bit 50 O 1 * +bit 49 O 1 * +bit 48 O 1 * +bit 47 O 1 * +bit 46 O 1 * +bit 45 O 1 * +bit 44 I 1 IO_157 +bit 43 O 1 IO_157 42 0 Z +bit 42 C 0 * +bit 41 I 1 IO_158 +bit 40 O 1 IO_158 39 0 Z +bit 39 C 0 * +bit 38 O 1 * +bit 37 O 1 * +bit 36 O 1 * +bit 35 O 1 * +bit 34 O 1 * +bit 33 O 1 * +bit 32 O 1 * +bit 31 O 1 * +bit 30 O 1 * +bit 29 O 1 * +bit 28 O 1 * +bit 27 O 1 * +bit 26 O 1 * +bit 25 O 1 * +bit 24 O 1 * +bit 23 I 1 IO_176 +bit 22 O 1 IO_176 21 0 Z +bit 21 C 0 * +bit 20 I 1 IO_177 +bit 19 O 1 IO_177 18 0 Z +bit 18 C 0 * +bit 17 I 1 IO_178 +bit 16 O 1 IO_178 15 0 Z +bit 15 C 0 * +bit 14 I 1 IO_179 +bit 13 O 1 IO_179 12 0 Z +bit 12 C 0 * +bit 11 I 1 IO_180 +bit 10 O 1 IO_180 9 0 Z +bit 9 C 0 * +bit 8 O 1 * +bit 7 O 1 * +bit 6 O 1 * +bit 5 O 1 * +bit 4 O 1 * +bit 3 O 1 * +bit 2 O 1 * +bit 1 O 1 * +bit 0 O 1 * diff --git a/jtag/data/xilinx/xc2c64a-vq44/STEPPINGS b/jtag/data/xilinx/xc2c64a-vq44/STEPPINGS new file mode 100644 index 00000000..1e22e783 --- /dev/null +++ b/jtag/data/xilinx/xc2c64a-vq44/STEPPINGS @@ -0,0 +1,21 @@ +# +# $Id: STEPPINGS,v 1.1 2003/02/14 11:14:56 telka Exp $ +# +# 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. +# + +# bits 31-28 of the Device Identification Register +0000 xc2c64a-vq44 0 diff --git a/jtag/data/xilinx/xc2c64a-vq44/xc2c64a-vq44 b/jtag/data/xilinx/xc2c64a-vq44/xc2c64a-vq44 new file mode 100644 index 00000000..7b1cab32 --- /dev/null +++ b/jtag/data/xilinx/xc2c64a-vq44/xc2c64a-vq44 @@ -0,0 +1,246 @@ +signal tdi +signal tck +signal tms +signal tdo +signal IO_0 +signal IO_1 +signal IO_2 +signal IO_8 +signal IO_9 +signal IO_10 +signal IO_11 +signal IO_12 +signal IO_16 +signal IO_17 +signal IO_20 +signal IO_21 +signal IO_22 +signal IO_23 +signal IO_25 +signal IO_27 +signal IO_28 +signal IO_32 +signal IO_33 +signal IO_34 +signal IO_37 +signal IO_41 +signal IO_42 +signal IO_43 +signal IO_45 +signal IO_46 +signal IO_48 +signal IO_49 +signal IO_54 +signal IO_58 +signal IO_60 +signal IO_61 +signal vdd1 +signal vdd2 +signal vdd3 +signal gnd1 +signal gnd2 +signal gnd3 + +register BSR 192 +register BR 1 +register DIR 32 + +instruction length 8 + +instruction BYPASS 11111111 BR +instruction SAMPLE/PRELOAD 00000011 BSR +instruction EXTEST 00000000 BSR +instruction IDCODE 00000001 DIR + +bit 191 I 1 IO_0 +bit 190 O 1 IO_0 189 0 Z +bit 189 C 0 * +bit 188 I 1 IO_1 +bit 187 O 1 IO_1 186 0 Z +bit 186 C 0 * +bit 185 I 1 IO_2 +bit 184 O 1 IO_2 183 0 Z +bit 183 C 0 * +bit 182 O 1 * +bit 181 O 1 * +bit 180 O 1 * +bit 179 O 1 * +bit 178 O 1 * +bit 177 O 1 * +bit 176 O 1 * +bit 175 O 1 * +bit 174 O 1 * +bit 173 O 1 * +bit 172 O 1 * +bit 171 O 1 * +bit 170 O 1 * +bit 169 O 1 * +bit 168 O 1 * +bit 167 I 1 IO_8 +bit 166 O 1 IO_8 165 0 Z +bit 165 C 0 * +bit 164 I 1 IO_9 +bit 163 O 1 IO_9 162 0 Z +bit 162 C 0 * +bit 161 I 1 IO_10 +bit 160 O 1 IO_10 159 0 Z +bit 159 C 0 * +bit 158 I 1 IO_11 +bit 157 O 1 IO_11 156 0 Z +bit 156 C 0 * +bit 155 I 1 IO_12 +bit 154 O 1 IO_12 153 0 Z +bit 153 C 0 * +bit 152 O 1 * +bit 151 O 1 * +bit 150 O 1 * +bit 149 O 1 * +bit 148 O 1 * +bit 147 O 1 * +bit 146 O 1 * +bit 145 O 1 * +bit 144 O 1 * +bit 143 I 1 IO_32 +bit 142 O 1 IO_32 141 0 Z +bit 141 C 0 * +bit 140 I 1 IO_33 +bit 139 O 1 IO_33 138 0 Z +bit 138 C 0 * +bit 137 I 1 IO_34 +bit 136 O 1 IO_34 135 0 Z +bit 135 C 0 * +bit 134 O 1 * +bit 133 O 1 * +bit 132 O 1 * +bit 131 O 1 * +bit 130 O 1 * +bit 129 O 1 * +bit 128 I 1 IO_37 +bit 127 O 1 IO_37 126 0 Z +bit 126 C 0 * +bit 125 O 1 * +bit 124 O 1 * +bit 123 O 1 * +bit 122 O 1 * +bit 121 O 1 * +bit 120 O 1 * +bit 119 O 1 * +bit 118 O 1 * +bit 117 O 1 * +bit 116 I 1 IO_41 +bit 115 O 1 IO_41 114 0 Z +bit 114 C 0 * +bit 113 I 1 IO_42 +bit 112 O 1 IO_42 111 0 Z +bit 111 C 0 * +bit 110 I 1 IO_43 +bit 109 O 1 IO_43 108 0 Z +bit 108 C 0 * +bit 107 O 1 * +bit 106 O 1 * +bit 105 O 1 * +bit 104 I 1 IO_45 +bit 103 O 1 IO_45 102 0 Z +bit 102 C 0 * +bit 101 I 1 IO_46 +bit 100 O 1 IO_46 99 0 Z +bit 99 C 0 * +bit 98 O 1 * +bit 97 O 1 * +bit 96 O 1 * +bit 95 I 1 IO_16 +bit 94 O 1 IO_16 93 0 Z +bit 93 C 0 * +bit 92 I 1 IO_17 +bit 91 O 1 IO_17 90 0 Z +bit 90 C 0 * +bit 89 O 1 * +bit 88 O 1 * +bit 87 O 1 * +bit 86 O 1 * +bit 85 O 1 * +bit 84 O 1 * +bit 83 I 1 IO_20 +bit 82 O 1 IO_20 81 0 Z +bit 81 C 0 * +bit 80 I 1 IO_21 +bit 79 O 1 IO_21 78 0 Z +bit 78 C 0 * +bit 77 I 1 IO_22 +bit 76 O 1 IO_22 75 0 Z +bit 75 C 0 * +bit 74 I 1 IO_23 +bit 73 O 1 IO_23 72 0 Z +bit 72 C 0 * +bit 71 O 1 * +bit 70 O 1 * +bit 69 O 1 * +bit 68 I 1 IO_25 +bit 67 O 1 IO_25 66 0 Z +bit 66 C 0 * +bit 65 O 1 * +bit 64 O 1 * +bit 63 O 1 * +bit 62 I 1 IO_27 +bit 61 O 1 IO_27 60 0 Z +bit 60 C 0 * +bit 59 I 1 IO_28 +bit 58 O 1 IO_28 57 0 Z +bit 57 C 0 * +bit 56 O 1 * +bit 55 O 1 * +bit 54 O 1 * +bit 53 O 1 * +bit 52 O 1 * +bit 51 O 1 * +bit 50 O 1 * +bit 49 O 1 * +bit 48 O 1 * +bit 47 I 1 IO_48 +bit 46 O 1 IO_48 45 0 Z +bit 45 C 0 * +bit 44 I 1 IO_49 +bit 43 O 1 IO_49 42 0 Z +bit 42 C 0 * +bit 41 O 1 * +bit 40 O 1 * +bit 39 O 1 * +bit 38 O 1 * +bit 37 O 1 * +bit 36 O 1 * +bit 35 O 1 * +bit 34 O 1 * +bit 33 O 1 * +bit 32 O 1 * +bit 31 O 1 * +bit 30 O 1 * +bit 29 I 1 IO_54 +bit 28 O 1 IO_54 27 0 Z +bit 27 C 0 * +bit 26 O 1 * +bit 25 O 1 * +bit 24 O 1 * +bit 23 O 1 * +bit 22 O 1 * +bit 21 O 1 * +bit 20 O 1 * +bit 19 O 1 * +bit 18 O 1 * +bit 17 I 1 IO_58 +bit 16 O 1 IO_58 15 0 Z +bit 15 C 0 * +bit 14 O 1 * +bit 13 O 1 * +bit 12 O 1 * +bit 11 I 1 IO_60 +bit 10 O 1 IO_60 9 0 Z +bit 9 C 0 * +bit 8 I 1 IO_61 +bit 7 O 1 IO_61 6 0 Z +bit 6 C 0 * +bit 5 I 1 IO_62 +bit 4 O 1 IO_62 3 0 Z +bit 3 C 0 * +bit 2 O 1 * +bit 1 O 1 * +bit 0 O 1 * diff --git a/jtag/include/Makefile.am b/jtag/include/Makefile.am index 052ddfa6..9204af9f 100644 --- a/jtag/include/Makefile.am +++ b/jtag/include/Makefile.am @@ -41,4 +41,5 @@ noinst_HEADERS = \ jtag.h \ tap.h \ fclock.h \ - setdevice.h + setdevice.h \ + xpcu.h diff --git a/jtag/include/cable.h b/jtag/include/cable.h index 24ecbf6b..467f7091 100644 --- a/jtag/include/cable.h +++ b/jtag/include/cable.h @@ -45,6 +45,7 @@ struct cable_driver_t { void (*done)( cable_t * ); void (*clock)( cable_t *, int, int ); int (*get_tdo)( cable_t * ); + int (*transfer)( cable_t *, int, char *, char * ); int (*set_trst)( cable_t *, int ); int (*get_trst)( cable_t * ); }; @@ -63,6 +64,7 @@ void cable_clock( cable_t *cable, int tms, int tdi ); int cable_get_tdo( cable_t *cable ); int cable_set_trst( cable_t *cable, int trst ); int cable_get_trst( cable_t *cable ); +int cable_transfer( cable_t *cable, int len, char *in, char *out ); void cable_set_frequency( cable_t *cable, uint32_t frequency ); uint32_t cable_get_frequency( cable_t *cable ); diff --git a/jtag/include/xpcu.h b/jtag/include/xpcu.h new file mode 100644 index 00000000..3d78ddd2 --- /dev/null +++ b/jtag/include/xpcu.h @@ -0,0 +1,24 @@ +#ifndef XPCU_H +#define XPCU_H 1 + +#include +#include + +#define XPCU_VID 0x03FD +#define XPCU_PID 0x0008 + +struct usb_device *find_xpcu(void); +int xpcu_init(); +int xpcu_close(struct usb_dev_handle *xpcu); +int xpcu_request_28(struct usb_dev_handle *xpcu, int value); +int xpcu_raise_ioa5(struct usb_dev_handle *xpcu); +int xpcu_write_gpio(struct usb_dev_handle *xpcu, uint8_t bits); +int xpcu_read_gpio(struct usb_dev_handle *xpcu, uint8_t *bits); +int xpcu_bitrev_test(struct usb_dev_handle *xpcu); +int xpcu_select_gpio(struct usb_dev_handle *xpcu, int select); +int xpcu_open(struct usb_dev_handle **xpcu); +int xpcu_request_a6(struct usb_dev_handle *xpcu, int nibbles, uint8_t *xmit, int inlen, uint8_t *recv); + + +#endif /* XPCU_H */ + diff --git a/jtag/src/cmd/cable.c b/jtag/src/cmd/cable.c index f481ac48..8b1f9be8 100644 --- a/jtag/src/cmd/cable.c +++ b/jtag/src/cmd/cable.c @@ -85,15 +85,20 @@ cmd_cable_help( void ) printf( _( "Usage: %s PORTADDR CABLE\n" "Usage: %s DEV CABLE\n" + "Usage: %s VID:PID:S/N CABLE\n" + "Usage: %s VID:PID:S/N CABLE\n" "Select JTAG cable connected to parallel port.\n" "\n" "PORTADDR parallel port address (e.g. 0x378)\n" "CABLE cable type\n" "DEV ppdev device (e.g. /dev/parport0)\n" + "VID empty or USB vendor ID, hex (e.g. 09FB)\n" + "PID empty or USB product ID, hex (e.g. 6001)\n" + "S/N empty or USB product serial number, ASCII\n" "\n" "List of supported cables:\n" "%-13s No cable connected\n" - ), "cable parallel", "cable ppdev", "none" ); + ), "cable parallel", "cable ppdev", "cable ftdi", "cable xpcu", "none" ); for (i = 0; cable_drivers[i]; i++) printf( _("%-13s %s\n"), cable_drivers[i]->name, _(cable_drivers[i]->description) ); diff --git a/jtag/src/part/data_register.c b/jtag/src/part/data_register.c index 9918be09..3b968f9d 100644 --- a/jtag/src/part/data_register.c +++ b/jtag/src/part/data_register.c @@ -47,8 +47,16 @@ data_register_alloc( const char *name, int len ) strncpy( dr->name, name, MAXLEN_DATA_REGISTER ); dr->name[MAXLEN_DATA_REGISTER] = '\0'; - dr->in = register_alloc( len ); - dr->out = register_alloc( len ); + if (len>0) + { + dr->in = register_alloc( len ); + dr->out = register_alloc( len ); + } + else + { + dr->in = register_alloc( 1 ); + dr->out = register_alloc( 1 ); + }; if (!dr->in || !dr->out) { free( dr->in ); free( dr->out ); diff --git a/jtag/src/tap/Makefile.am b/jtag/src/tap/Makefile.am index 03b5fa79..c8f809f9 100644 --- a/jtag/src/tap/Makefile.am +++ b/jtag/src/tap/Makefile.am @@ -33,12 +33,17 @@ libtap_a_SOURCES = \ parport.c \ parport/direct.c \ parport/ppdev.c \ + parport/xpcu_common.c \ + parport/xpcu_pp.c \ + parport/ftdi.c \ cable.c \ cable/generic.h \ cable/generic.c \ cable/arcom.c \ cable/byteblaster.c \ + cable/usbblaster.c \ cable/dlc5.c \ + cable/xpc.c \ cable/ea253.c \ cable/ei012.c \ cable/keithkoep.c \ diff --git a/jtag/src/tap/cable.c b/jtag/src/tap/cable.c index c41d01aa..75bdac87 100644 --- a/jtag/src/tap/cable.c +++ b/jtag/src/tap/cable.c @@ -37,6 +37,7 @@ extern cable_driver_t arcom_cable_driver; extern cable_driver_t byteblaster_cable_driver; +extern cable_driver_t usbblaster_cable_driver; extern cable_driver_t dlc5_cable_driver; extern cable_driver_t ea253_cable_driver; extern cable_driver_t ei012_cable_driver; @@ -47,10 +48,16 @@ extern cable_driver_t mpcbdm_cable_driver; extern cable_driver_t triton_cable_driver; extern cable_driver_t wiggler_cable_driver; extern cable_driver_t wiggler2_cable_driver; +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; +#endif cable_driver_t *cable_drivers[] = { &arcom_cable_driver, &byteblaster_cable_driver, + &usbblaster_cable_driver, &dlc5_cable_driver, &ea253_cable_driver, &ei012_cable_driver, @@ -61,6 +68,10 @@ cable_driver_t *cable_drivers[] = { &triton_cable_driver, &wiggler_cable_driver, &wiggler2_cable_driver, +#ifdef HAVE_LIBUSB + &xpc_int_cable_driver, + &xpc_ext_cable_driver, +#endif NULL /* last must be NULL */ }; @@ -178,6 +189,14 @@ cable_get_frequency( cable_t *cable ) return frequency; } +int +cable_transfer( cable_t *cable, int len, char *in, char *out ) +{ + int r; + r=cable->driver->transfer( cable, len, in, out ); + return r; +} + void cable_wait( void ) { diff --git a/jtag/src/tap/cable/arcom.c b/jtag/src/tap/cable/arcom.c index 16e62d47..d406da0e 100644 --- a/jtag/src/tap/cable/arcom.c +++ b/jtag/src/tap/cable/arcom.c @@ -105,6 +105,7 @@ cable_driver_t arcom_cable_driver = { generic_done, arcom_clock, arcom_get_tdo, + generic_transfer, arcom_set_trst, generic_get_trst }; diff --git a/jtag/src/tap/cable/byteblaster.c b/jtag/src/tap/cable/byteblaster.c index 04aabfcd..3fb67d3e 100644 --- a/jtag/src/tap/cable/byteblaster.c +++ b/jtag/src/tap/cable/byteblaster.c @@ -131,6 +131,7 @@ cable_driver_t byteblaster_cable_driver = { generic_done, byteblaster_clock, byteblaster_get_tdo, + generic_transfer, byteblaster_set_trst, generic_get_trst }; diff --git a/jtag/src/tap/cable/dlc5.c b/jtag/src/tap/cable/dlc5.c index ecce9c5d..1db1c78c 100644 --- a/jtag/src/tap/cable/dlc5.c +++ b/jtag/src/tap/cable/dlc5.c @@ -102,6 +102,7 @@ cable_driver_t dlc5_cable_driver = { generic_done, dlc5_clock, dlc5_get_tdo, + generic_transfer, dlc5_set_trst, generic_get_trst }; diff --git a/jtag/src/tap/cable/ea253.c b/jtag/src/tap/cable/ea253.c index 537ace22..8c2b68eb 100644 --- a/jtag/src/tap/cable/ea253.c +++ b/jtag/src/tap/cable/ea253.c @@ -105,6 +105,7 @@ cable_driver_t ea253_cable_driver = { generic_done, ea253_clock, ea253_get_tdo, + generic_transfer, ea253_set_trst, generic_get_trst }; diff --git a/jtag/src/tap/cable/ei012.c b/jtag/src/tap/cable/ei012.c index f95b3183..b4ba3f33 100644 --- a/jtag/src/tap/cable/ei012.c +++ b/jtag/src/tap/cable/ei012.c @@ -107,6 +107,7 @@ cable_driver_t ei012_cable_driver = { generic_done, ei012_clock, ei012_get_tdo, + generic_transfer, ei012_set_trst, generic_get_trst }; diff --git a/jtag/src/tap/cable/generic.c b/jtag/src/tap/cable/generic.c index 61191482..7495acd9 100644 --- a/jtag/src/tap/cable/generic.c +++ b/jtag/src/tap/cable/generic.c @@ -70,6 +70,24 @@ generic_done( cable_t *cable ) parport_close( cable->port ); } +int +generic_transfer( cable_t *cable, int len, char *in, char *out ) +{ + int i; + + if(out) + for(i=0; i Cable Driver + * Copyright (C) 2006 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, 2006; http://www.ixo.de + * + */ + +#include "sysdep.h" + +#include "cable.h" +#include "parport.h" +#include "chain.h" + +#include "generic.h" + +#define TCK 0 +#define TMS 1 +#define TDI 4 +#define READ 6 +#define SHMODE 7 +#define OTHERS ((1<<2)|(1<<3)|(1<<5)) + +#define TDO 0 + +static int +usbblaster_init( cable_t *cable ) +{ + int i; + + if (parport_open( cable->port )) + return -1; + + for(i=0;i<64;i++) + parport_set_data( cable->port, 0 ); + + parport_set_control( cable->port, 1 ); // flush + parport_set_control( cable->port, 0 ); // noflush + + return 0; +} + +static void +usbblaster_clock( cable_t *cable, int tms, int tdi ) +{ + tms = tms ? 1 : 0; + tdi = tdi ? 1 : 0; + + parport_set_data( cable->port, OTHERS | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_data( cable->port, OTHERS | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + parport_set_control( cable->port, 1 ); // flush + parport_set_control( cable->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 +#if 0 + { + char x = ( parport_get_data( cable->port ) & (1 << TDO)) ? 1 : 0; + printf("GetTDO %d\n", x); + return x; + } +#else + return ( parport_get_data( cable->port ) & (1 << TDO)) ? 1 : 0; +#endif +} + +static int +usbblaster_set_trst( cable_t *cable, int trst ) +{ + return 1; +} + +static int +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 */ + + while(len - in_offset >= 8) + { + int i; + int chunkbytes = ((len-in_offset)>>3); + if(chunkbytes > 63) chunkbytes = 63; + + if(out) + parport_set_data( cable->port,(1<port,(1<port, b ); + }; + + if(out) + { + parport_set_control( cable->port, 1 ); // flush + parport_set_control( cable->port, 0 ); + + for(i=0; iport ); +#if 0 + printf("read byte: %02X\n", b); +#endif + + for(j=1; j<256; j<<=1) out[out_offset++] = (b & j) ? 1:0; + }; + }; + }; + + 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)); + } + + if(out) + { + parport_set_control( cable->port, 1 ); // flush + parport_set_control( cable->port, 0 ); + + while(len > out_offset) + out[out_offset++] = ( parport_get_data( cable->port ) & (1 << TDO)) ? 1 : 0; + } + + return 0; +} + +cable_driver_t usbblaster_cable_driver = { + "UsbBlaster", + N_("Altera USB-Blaster Cable"), + generic_connect, + generic_disconnect, + generic_cable_free, + usbblaster_init, + generic_done, + usbblaster_clock, + usbblaster_get_tdo, + usbblaster_transfer, + usbblaster_set_trst, + generic_get_trst +}; diff --git a/jtag/src/tap/cable/wiggler.c b/jtag/src/tap/cable/wiggler.c index 7d3b4e36..8e1aaa98 100644 --- a/jtag/src/tap/cable/wiggler.c +++ b/jtag/src/tap/cable/wiggler.c @@ -113,6 +113,7 @@ cable_driver_t wiggler_cable_driver = { generic_done, wiggler_clock, wiggler_get_tdo, + generic_transfer, wiggler_set_trst, generic_get_trst }; @@ -127,6 +128,7 @@ cable_driver_t igloo_cable_driver = { generic_done, wiggler_clock, wiggler_get_tdo, + generic_transfer, wiggler_set_trst, generic_get_trst }; diff --git a/jtag/src/tap/cable/wiggler2.c b/jtag/src/tap/cable/wiggler2.c index 0af23d44..4001b466 100644 --- a/jtag/src/tap/cable/wiggler2.c +++ b/jtag/src/tap/cable/wiggler2.c @@ -121,6 +121,7 @@ cable_driver_t wiggler2_cable_driver = { generic_done, wiggler2_clock, wiggler2_get_tdo, + generic_transfer, wiggler2_set_trst, generic_get_trst }; diff --git a/jtag/src/tap/cable/xpc.c b/jtag/src/tap/cable/xpc.c new file mode 100644 index 00000000..398d9b02 --- /dev/null +++ b/jtag/src/tap/cable/xpc.c @@ -0,0 +1,122 @@ +/* + * $Id: xpc.c,v 1.8 2003/08/19 08:42:20 telka Exp $ + * + * 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 + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by Marcel Telka , 2002, 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" + +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; + + PARAM_TRST(cable) = 1; + + return 0; +} + +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; + + PARAM_TRST(cable) = 1; + + return 0; +} + + +#define PROG 3 +#define TCK 2 +#define TMS 1 +#define TDI 0 +#define TDO 0 + +static void +xpc_clock( cable_t *cable, int tms, int tdi ) +{ + tms = tms ? 1 : 0; + tdi = tdi ? 1 : 0; + + parport_set_data( cable->port, (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + cable_wait(); + parport_set_data( cable->port, (1 << PROG) | (1 << TCK) | (tms << TMS) | (tdi << TDI) ); + cable_wait(); + parport_set_data( cable->port, (1 << PROG) | (0 << TCK) | (tms << TMS) | (tdi << TDI) ); + cable_wait(); +} + +static int +xpc_get_tdo( cable_t *cable ) +{ + return (parport_get_data( cable->port ) >> TDO) & 1; +} + +static int +xpc_set_trst( cable_t *cable, int trst ) +{ + return 1; +} + +cable_driver_t xpc_int_cable_driver = { + "xpc_int", + N_("Xilinx Platform Cable USB internal chain"), + generic_connect, + generic_disconnect, + generic_cable_free, + xpc_int_init, + generic_done, + xpc_clock, + xpc_get_tdo, + generic_transfer, + xpc_set_trst, + generic_get_trst +}; + +cable_driver_t xpc_ext_cable_driver = { + "xpc_ext", + N_("Xilinx Platform Cable USB external chain"), + generic_connect, + generic_disconnect, + generic_cable_free, + xpc_ext_init, + generic_done, + xpc_clock, + xpc_get_tdo, + generic_transfer, + xpc_set_trst, + generic_get_trst +}; + diff --git a/jtag/src/tap/parport.c b/jtag/src/tap/parport.c index c49924ec..28d26d2e 100644 --- a/jtag/src/tap/parport.c +++ b/jtag/src/tap/parport.c @@ -32,6 +32,12 @@ extern parport_driver_t direct_parport_driver; #ifdef HAVE_LINUX_PPDEV_H extern parport_driver_t ppdev_parport_driver; #endif /* HAVE_LINUX_PPDEV_H */ +#ifdef HAVE_LIBFTDI +extern parport_driver_t ftdi_parport_driver; +#endif /* HAVE_LIBFTDI */ +#ifdef HAVE_LIBUSB +extern parport_driver_t xpcu_pp_driver; +#endif /* HAVE_LIBUSB */ parport_driver_t *parport_drivers[] = { #if defined(HAVE_IOPERM) || defined(HAVE_I386_SET_IOPERM) @@ -40,6 +46,12 @@ parport_driver_t *parport_drivers[] = { #ifdef HAVE_LINUX_PPDEV_H &ppdev_parport_driver, #endif /* HAVE_LINUX_PPDEV_H */ +#ifdef HAVE_LIBFTDI + &ftdi_parport_driver, +#endif /* HAVE_LIBFTDI */ +#ifdef HAVE_LIBUSB + &xpcu_pp_driver, +#endif /* HAVE_LIBUSB */ NULL /* last must be NULL */ }; @@ -78,3 +90,4 @@ parport_set_control( parport_t *port, uint8_t data ) { return port->driver->set_control( port, data ); } + diff --git a/jtag/src/tap/parport/ftdi.c b/jtag/src/tap/parport/ftdi.c new file mode 100644 index 00000000..e2263b0d --- /dev/null +++ b/jtag/src/tap/parport/ftdi.c @@ -0,0 +1,357 @@ +/* + * $Id: ftdi.c,v 1.7 2003/08/19 09:05:25 telka Exp $ + * + * libftdi Driver + * Copyright (C) 2006 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, 2006. + * Structure taken from ppdev.c, written by Marcel Telka, 2003. + * + */ + +#include "sysdep.h" + +#ifdef HAVE_LIBFTDI + +#include +#include +#include +#include + +#include +#include + +#include + +#include "parport.h" +#include "cable.h" + +parport_driver_t ftdi_parport_driver; + +typedef struct port_node_t port_node_t; + +struct port_node_t { + parport_t *port; + port_node_t *next; +}; + +static port_node_t *ports = NULL; /* devices */ + +#define OUTBUF_LEN 64 + +typedef struct { + char *serial; + unsigned int vendor_id; + unsigned int product_id; + char autoflush; + struct ftdi_context *fc; + unsigned char outcount; + unsigned char *outbuf; +} ftdi_params_t; + +static int ftdi_flush_output ( ftdi_params_t *p ); + +static parport_t * +ftdi_parport_alloc( const char *vidpid ) +{ + ftdi_params_t *params = malloc( sizeof *params ); + parport_t *parport = malloc( sizeof *parport ); + port_node_t *node = malloc( sizeof *node ); + struct ftdi_context *fc = malloc( sizeof(struct ftdi_context) ); + unsigned char *outbuf = malloc( OUTBUF_LEN ); + + if (!node || !parport || !params || !fc || !outbuf) { + free( node ); + free( parport ); + free( params ); + free( fc ); + return NULL; + } + + ftdi_init(fc); + params->outbuf = outbuf; + params->outcount = 0; + params->autoflush = 0; + params->product_id = 0; + params->vendor_id = 0; + params->serial = NULL; + params->fc = fc; + + { + 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 = &ftdi_parport_driver; + parport->cable = NULL; + + node->port = parport; + node->next = ports; + + ports = node; + + return parport; +} + +static void +ftdi_parport_free( parport_t *port ) +{ + port_node_t **prev; + + for (prev = &ports; *prev; prev = &((*prev)->next)) + if ((*prev)->port == port) + break; + + if (*prev) { + port_node_t *pn = *prev; + *prev = pn->next; + free( pn ); + } + + free( ((ftdi_params_t *) port->params)->serial ); + free( ((ftdi_params_t *) port->params)->outbuf ); + free( ((ftdi_params_t *) port->params)->fc ); + free( port->params ); + free( port ); +} + +static cable_t * +ftdi_connect( const char **par, int parnum ) +{ + int i; + port_node_t *pn; + parport_t *parport; + cable_t *cable; + + if (parnum != 2) { + printf( _("Syntax error!\n") ); + return NULL; + } + + for (pn = ports; pn; pn = pn->next) + if (strcmp( pn->port->params, par[0] ) == 0) { + printf( _("Disconnecting %s from FTDI device %s\n"), _(pn->port->cable->driver->description), par[0] ); + pn->port->cable->driver->disconnect( pn->port->cable ); + break; + } + + if (strcmp( par[1], "none" ) == 0) { + printf( _("Changed cable to 'none'\n") ); + return NULL; + } + + for (i = 0; cable_drivers[i]; i++) + if (strcmp( par[1], cable_drivers[i]->name ) == 0) + break; + + if (!cable_drivers[i]) { + printf( _("Unknown cable: %s\n"), par[1] ); + return NULL; + } + + printf( _("Initializing %s on FTDI device %s\n"), _(cable_drivers[i]->description), par[0] ); + + parport = ftdi_parport_alloc( par[0] ); + if (!parport) { + printf( _("%s(%d) Out of memory.\n"), __FILE__, __LINE__ ); + return NULL; + } + + cable = cable_drivers[i]->connect( cable_drivers[i], parport ); + if (!cable) + ftdi_parport_free( parport ); + + return cable; +} + +static int +ftdi_open( parport_t *parport ) +{ + int r; + ftdi_params_t *p = parport->params; + struct ftdi_context *fc = p->fc; + + /* Try to be intelligent about IDs */ + + if(p->vendor_id) + r = ftdi_usb_open_desc(fc, p->vendor_id, p->product_id, NULL, p->serial); /* USB-Blaster */ + else + { + r = ftdi_usb_open_desc(fc, 0x09FB, 0x6001, NULL, p->serial); /* USB-Blaster */ + if(r<0) r = ftdi_usb_open_desc(fc, 0x09FB, 0x6002, NULL, p->serial); /* Cubic Cyclonium */ + if(r<0) r = ftdi_usb_open_desc(fc, 0x09FB, 0x6003, NULL, p->serial); /* NIOS II Evaluation board */ + if(r<0) r = ftdi_usb_open_desc(fc, 0x16C0, 0x06AD, NULL, p->serial); /* http://www.ixo.de/info/usb_jtag/ */ + }; + + if(r<0) + { + fprintf (stderr, "Can't open ftdi device: %s\n", + ftdi_get_error_string (fc)); + ftdi_deinit(fc); + return -1; + }; + + (void)ftdi_disable_bitbang(fc); + + if(ftdi_set_latency_timer(fc, 2)<0) + { + fprintf (stderr, "Can't set minimum latency: %s\n", + ftdi_get_error_string (fc)); + ftdi_usb_close(fc); + ftdi_deinit(fc); + return -1; + }; + +#if 1 + /* libftdi 0.6 doesn't allow high baudrates, so we send the control + message outselves */ + + if (usb_control_msg(fc->usb_dev, 0x40, 3, 1, 0, NULL, 0, fc->usb_write_timeout) != 0) + { + fprintf (stderr, "Can't set max baud rate.\n"); + ftdi_usb_close(fc); + ftdi_deinit(fc); + return -1; + }; +#else + if(ftdi_set_baudrate(fc, 48000000)<0) + { + fprintf (stderr, "Can't set max baud rate: %s\n", + ftdi_get_error_string (fc)); + ftdi_usb_close(fc); + ftdi_deinit(fc); + return -1; + }; +#endif + + return 0; +} + +static int +ftdi_flush_output ( ftdi_params_t *p ) +{ + int xferred; + + xferred = ftdi_write_data(p->fc, p->outbuf, p->outcount); + + if(xferred > 0 && xferred < p->outcount) + { + int offset = xferred; + int remaining = p->outcount - xferred; + + while(remaining) + { + printf("W\n"); + if(xferred < 0) return xferred; + xferred = ftdi_write_data(p->fc, p->outbuf + offset, remaining); + if(xferred < 0) + { + memmove(p->outbuf, p->outbuf + offset, remaining); + p->outcount = remaining; + return 0; + } + offset += xferred; + remaining -= xferred; + } + }; + p->outcount = 0; + + return 0; +} + +static int +ftdi_close( parport_t *parport ) +{ + ftdi_params_t *p = parport->params; + + if(p->outcount > 0) ftdi_flush_output( p ); + p->outcount = 0; + + ftdi_usb_close(p->fc); + ftdi_deinit(p->fc); + + return 0; +} + +static int +ftdi_set_data( parport_t *parport, uint8_t data ) +{ + ftdi_params_t *p = parport->params; + + if(p->autoflush) + { + if(ftdi_write_data(p->fc, &data, 1) != 1) printf("w\n"); + } + else + { + p->outbuf[p->outcount++] = data; + + if(p->outcount >= OUTBUF_LEN) + return ftdi_flush_output( p ); + }; + + return 0; +} + +static int +ftdi_get_data( parport_t *parport ) +{ + unsigned char d; + ftdi_params_t *p = parport->params; + + while(ftdi_read_data( p->fc, &d, 1) == 0); + return d; +} + +static int +ftdi_get_status( parport_t *parport ) +{ + return 0; +} + +static int +ftdi_set_control( parport_t *parport, uint8_t data ) +{ + ftdi_params_t *p = parport->params; + + p->autoflush = data; + if(p->autoflush) ftdi_flush_output( p ); + + return 0; +} + +parport_driver_t ftdi_parport_driver = { + "ftdi", + ftdi_connect, + ftdi_parport_free, + ftdi_open, + ftdi_close, + ftdi_set_data, + ftdi_get_data, + ftdi_get_status, + ftdi_set_control +}; + +#endif /* HAVE_LIBFTDI */ diff --git a/jtag/src/tap/parport/xpcu_common.c b/jtag/src/tap/parport/xpcu_common.c new file mode 100644 index 00000000..27edc424 --- /dev/null +++ b/jtag/src/tap/parport/xpcu_common.c @@ -0,0 +1,286 @@ +/* + * $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 +#include +#include +#include +#include +#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, 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 new file mode 100644 index 00000000..0680251f --- /dev/null +++ b/jtag/src/tap/parport/xpcu_pp.c @@ -0,0 +1,282 @@ +/* + * $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 +#include +#include +#include +#include +#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 ); +} + +/* ---------------------------------------------------------------------- */ + +static cable_t * +xpcu_pp_connect( const char **par, int parnum ) +{ + int i; + port_node_t *pn; + parport_t *parport; + cable_t *cable; + + if (parnum != 2) { + 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; + } + + if (strcmp( par[1], "none" ) == 0) { + printf( _("Changed cable to 'none'\n") ); + return NULL; + } + + for (i = 0; cable_drivers[i]; i++) + if (strcmp( par[1], cable_drivers[i]->name ) == 0) + break; + + if (!cable_drivers[i]) { + printf( _("Unknown cable: %s\n"), par[1] ); + return NULL; + } + + printf( _("Initializing %s, device %s\n"), _(cable_drivers[i]->description), par[0] ); + + parport = xpcu_pp_alloc( par[0] ); + if (!parport) { + printf( _("%s(%d) Out of memory.\n"), __FILE__, __LINE__ ); + return NULL; + } + + cable = cable_drivers[i]->connect( cable_drivers[i], parport ); + if (!cable) + xpcu_pp_free( parport ); + + return cable; +} + +/* ---------------------------------------------------------------------- */ + +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/tap.c b/jtag/src/tap/tap.c index e0b6de0c..5da6e269 100644 --- a/jtag/src/tap/tap.c +++ b/jtag/src/tap/tap.c @@ -56,7 +56,17 @@ tap_shift_register( chain_t *chain, const tap_register *in, tap_register *out, i /* Capture-DR, Capture-IR, Shift-DR, Shift-IR, Exit2-DR or Exit2-IR state */ if (tap_state( chain ) & TAPSTAT_CAPTURE) chain_clock( chain, 0, 0 ); /* save last TDO bit :-) */ - for (i = 0; i < in->len; i++) { + + i = in->len; + if(exit) i--; + if(out && out->len < i) i = out->len; + + if(out) + cable_transfer( chain->cable, i, in->data, out->data ); + else + cable_transfer( chain->cable, i, in->data, NULL ); + + for (; i < in->len; i++) { if (out && (i < out->len)) out->data[i] = cable_get_tdo( chain->cable ); chain_clock( chain, (exit != EXITMODE_SHIFT && ((i + 1) == in->len)) ? 1 : 0, in->data[i] ); /* Shift (& Exit1) */