1 /* 2 * Porting to u-boot: 3 * 4 * (C) Copyright 2010 5 * Stefano Babic, DENX Software Engineering, sbabic@denx.de. 6 * 7 * Lattice ispVME Embedded code to load Lattice's FPGA: 8 * 9 * Copyright 2009 Lattice Semiconductor Corp. 10 * 11 * ispVME Embedded allows programming of Lattice's suite of FPGA 12 * devices on embedded systems through the JTAG port. The software 13 * is distributed in source code form and is open to re - distribution 14 * and modification where applicable. 15 * 16 * Revision History of ivm_core.c module: 17 * 4/25/06 ht Change some variables from unsigned short or int 18 * to long int to make the code compiler independent. 19 * 5/24/06 ht Support using RESET (TRST) pin as a special purpose 20 * control pin such as triggering the loading of known 21 * state exit. 22 * 3/6/07 ht added functions to support output to terminals 23 * 24 * 09/11/07 NN Type cast mismatch variables 25 * Moved the sclock() function to hardware.c 26 * 08/28/08 NN Added Calculate checksum support. 27 * 4/1/09 Nguyen replaced the recursive function call codes on 28 * the ispVMLCOUNT function 29 * See file CREDITS for list of people who contributed to this 30 * project. 31 * 32 * This program is free software; you can redistribute it and/or 33 * modify it under the terms of the GNU General Public License as 34 * published by the Free Software Foundation; either version 2 of 35 * the License, or (at your option) any later version. 36 * 37 * This program is distributed in the hope that it will be useful, 38 * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 40 * GNU General Public License for more details. 41 * 42 * You should have received a copy of the GNU General Public License 43 * along with this program; if not, write to the Free Software 44 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 45 * MA 02111-1307 USA 46 */ 47 48 #include <common.h> 49 #include <linux/string.h> 50 #include <malloc.h> 51 #include <lattice.h> 52 53 #define vme_out_char(c) printf("%c", c) 54 #define vme_out_hex(c) printf("%x", c) 55 #define vme_out_string(s) printf("%s", s) 56 57 /* 58 * 59 * Global variables used to specify the flow control and data type. 60 * 61 * g_usFlowControl: flow control register. Each bit in the 62 * register can potentially change the 63 * personality of the embedded engine. 64 * g_usDataType: holds the data type of the current row. 65 * 66 */ 67 68 static unsigned short g_usFlowControl; 69 unsigned short g_usDataType; 70 71 /* 72 * 73 * Global variables used to specify the ENDDR and ENDIR. 74 * 75 * g_ucEndDR: the state that the device goes to after SDR. 76 * g_ucEndIR: the state that the device goes to after SIR. 77 * 78 */ 79 80 unsigned char g_ucEndDR = DRPAUSE; 81 unsigned char g_ucEndIR = IRPAUSE; 82 83 /* 84 * 85 * Global variables used to support header/trailer. 86 * 87 * g_usHeadDR: the number of lead devices in bypass. 88 * g_usHeadIR: the sum of IR length of lead devices. 89 * g_usTailDR: the number of tail devices in bypass. 90 * g_usTailIR: the sum of IR length of tail devices. 91 * 92 */ 93 94 static unsigned short g_usHeadDR; 95 static unsigned short g_usHeadIR; 96 static unsigned short g_usTailDR; 97 static unsigned short g_usTailIR; 98 99 /* 100 * 101 * Global variable to store the number of bits of data or instruction 102 * to be shifted into or out from the device. 103 * 104 */ 105 106 static unsigned short g_usiDataSize; 107 108 /* 109 * 110 * Stores the frequency. Default to 1 MHz. 111 * 112 */ 113 114 static int g_iFrequency = 1000; 115 116 /* 117 * 118 * Stores the maximum amount of ram needed to hold a row of data. 119 * 120 */ 121 122 static unsigned short g_usMaxSize; 123 124 /* 125 * 126 * Stores the LSH or RSH value. 127 * 128 */ 129 130 static unsigned short g_usShiftValue; 131 132 /* 133 * 134 * Stores the current repeat loop value. 135 * 136 */ 137 138 static unsigned short g_usRepeatLoops; 139 140 /* 141 * 142 * Stores the current vendor. 143 * 144 */ 145 146 static signed char g_cVendor = LATTICE; 147 148 /* 149 * 150 * Stores the VME file CRC. 151 * 152 */ 153 154 unsigned short g_usCalculatedCRC; 155 156 /* 157 * 158 * Stores the Device Checksum. 159 * 160 */ 161 /* 08/28/08 NN Added Calculate checksum support. */ 162 unsigned long g_usChecksum; 163 static unsigned int g_uiChecksumIndex; 164 165 /* 166 * 167 * Stores the current state of the JTAG state machine. 168 * 169 */ 170 171 static signed char g_cCurrentJTAGState; 172 173 /* 174 * 175 * Global variables used to support looping. 176 * 177 * g_pucHeapMemory: holds the entire repeat loop. 178 * g_iHeapCounter: points to the current byte in the repeat loop. 179 * g_iHEAPSize: the current size of the repeat in bytes. 180 * 181 */ 182 183 unsigned char *g_pucHeapMemory; 184 unsigned short g_iHeapCounter; 185 unsigned short g_iHEAPSize; 186 static unsigned short previous_size; 187 188 /* 189 * 190 * Global variables used to support intelligent programming. 191 * 192 * g_usIntelDataIndex: points to the current byte of the 193 * intelligent buffer. 194 * g_usIntelBufferSize: holds the size of the intelligent 195 * buffer. 196 * 197 */ 198 199 unsigned short g_usIntelDataIndex; 200 unsigned short g_usIntelBufferSize; 201 202 /* 203 * 204 * Supported VME versions. 205 * 206 */ 207 208 const char *const g_szSupportedVersions[] = { 209 "__VME2.0", "__VME3.0", "____12.0", "____12.1", 0}; 210 211 /* 212 * 213 * Holds the maximum size of each respective buffer. These variables are used 214 * to write the HEX files when converting VME to HEX. 215 * 216 */ 217 218 static unsigned short g_usTDOSize; 219 static unsigned short g_usMASKSize; 220 static unsigned short g_usTDISize; 221 static unsigned short g_usDMASKSize; 222 static unsigned short g_usLCOUNTSize; 223 static unsigned short g_usHDRSize; 224 static unsigned short g_usTDRSize; 225 static unsigned short g_usHIRSize; 226 static unsigned short g_usTIRSize; 227 static unsigned short g_usHeapSize; 228 229 /* 230 * 231 * Global variables used to store data. 232 * 233 * g_pucOutMaskData: local RAM to hold one row of MASK data. 234 * g_pucInData: local RAM to hold one row of TDI data. 235 * g_pucOutData: local RAM to hold one row of TDO data. 236 * g_pucHIRData: local RAM to hold the current SIR header. 237 * g_pucTIRData: local RAM to hold the current SIR trailer. 238 * g_pucHDRData: local RAM to hold the current SDR header. 239 * g_pucTDRData: local RAM to hold the current SDR trailer. 240 * g_pucIntelBuffer: local RAM to hold the current intelligent buffer 241 * g_pucOutDMaskData: local RAM to hold one row of DMASK data. 242 * 243 */ 244 245 unsigned char *g_pucOutMaskData = NULL, 246 *g_pucInData = NULL, 247 *g_pucOutData = NULL, 248 *g_pucHIRData = NULL, 249 *g_pucTIRData = NULL, 250 *g_pucHDRData = NULL, 251 *g_pucTDRData = NULL, 252 *g_pucIntelBuffer = NULL, 253 *g_pucOutDMaskData = NULL; 254 255 /* 256 * 257 * JTAG state machine transition table. 258 * 259 */ 260 261 struct { 262 unsigned char CurState; /* From this state */ 263 unsigned char NextState; /* Step to this state */ 264 unsigned char Pattern; /* The tragetory of TMS */ 265 unsigned char Pulses; /* The number of steps */ 266 } g_JTAGTransistions[25] = { 267 { RESET, RESET, 0xFC, 6 }, /* Transitions from RESET */ 268 { RESET, IDLE, 0x00, 1 }, 269 { RESET, DRPAUSE, 0x50, 5 }, 270 { RESET, IRPAUSE, 0x68, 6 }, 271 { IDLE, RESET, 0xE0, 3 }, /* Transitions from IDLE */ 272 { IDLE, DRPAUSE, 0xA0, 4 }, 273 { IDLE, IRPAUSE, 0xD0, 5 }, 274 { DRPAUSE, RESET, 0xF8, 5 }, /* Transitions from DRPAUSE */ 275 { DRPAUSE, IDLE, 0xC0, 3 }, 276 { DRPAUSE, IRPAUSE, 0xF4, 7 }, 277 { DRPAUSE, DRPAUSE, 0xE8, 6 },/* 06/14/06 Support POLL STATUS LOOP*/ 278 { IRPAUSE, RESET, 0xF8, 5 }, /* Transitions from IRPAUSE */ 279 { IRPAUSE, IDLE, 0xC0, 3 }, 280 { IRPAUSE, DRPAUSE, 0xE8, 6 }, 281 { DRPAUSE, SHIFTDR, 0x80, 2 }, /* Extra transitions using SHIFTDR */ 282 { IRPAUSE, SHIFTDR, 0xE0, 5 }, 283 { SHIFTDR, DRPAUSE, 0x80, 2 }, 284 { SHIFTDR, IDLE, 0xC0, 3 }, 285 { IRPAUSE, SHIFTIR, 0x80, 2 },/* Extra transitions using SHIFTIR */ 286 { SHIFTIR, IRPAUSE, 0x80, 2 }, 287 { SHIFTIR, IDLE, 0xC0, 3 }, 288 { DRPAUSE, DRCAPTURE, 0xE0, 4 }, /* 11/15/05 Support DRCAPTURE*/ 289 { DRCAPTURE, DRPAUSE, 0x80, 2 }, 290 { IDLE, DRCAPTURE, 0x80, 2 }, 291 { IRPAUSE, DRCAPTURE, 0xE0, 4 } 292 }; 293 294 /* 295 * 296 * List to hold all LVDS pairs. 297 * 298 */ 299 300 LVDSPair *g_pLVDSList; 301 unsigned short g_usLVDSPairCount; 302 303 /* 304 * 305 * Function prototypes. 306 * 307 */ 308 309 static signed char ispVMDataCode(void); 310 static long int ispVMDataSize(void); 311 static void ispVMData(unsigned char *Data); 312 static signed char ispVMShift(signed char Code); 313 static signed char ispVMAmble(signed char Code); 314 static signed char ispVMLoop(unsigned short a_usLoopCount); 315 static signed char ispVMBitShift(signed char mode, unsigned short bits); 316 static void ispVMComment(unsigned short a_usCommentSize); 317 static void ispVMHeader(unsigned short a_usHeaderSize); 318 static signed char ispVMLCOUNT(unsigned short a_usCountSize); 319 static void ispVMClocks(unsigned short Clocks); 320 static void ispVMBypass(signed char ScanType, unsigned short Bits); 321 static void ispVMStateMachine(signed char NextState); 322 static signed char ispVMSend(unsigned short int); 323 static signed char ispVMRead(unsigned short int); 324 static signed char ispVMReadandSave(unsigned short int); 325 static signed char ispVMProcessLVDS(unsigned short a_usLVDSCount); 326 static void ispVMMemManager(signed char types, unsigned short size); 327 328 /* 329 * 330 * External variables and functions in hardware.c module 331 * 332 */ 333 static signed char g_cCurrentJTAGState; 334 335 #ifdef DEBUG 336 337 /* 338 * 339 * GetState 340 * 341 * Returns the state as a string based on the opcode. Only used 342 * for debugging purposes. 343 * 344 */ 345 346 const char *GetState(unsigned char a_ucState) 347 { 348 switch (a_ucState) { 349 case RESET: 350 return "RESET"; 351 case IDLE: 352 return "IDLE"; 353 case IRPAUSE: 354 return "IRPAUSE"; 355 case DRPAUSE: 356 return "DRPAUSE"; 357 case SHIFTIR: 358 return "SHIFTIR"; 359 case SHIFTDR: 360 return "SHIFTDR"; 361 case DRCAPTURE:/* 11/15/05 support DRCAPTURE*/ 362 return "DRCAPTURE"; 363 default: 364 break; 365 } 366 367 return 0; 368 } 369 370 /* 371 * 372 * PrintData 373 * 374 * Prints the data. Only used for debugging purposes. 375 * 376 */ 377 378 void PrintData(unsigned short a_iDataSize, unsigned char *a_pucData) 379 { 380 /* 09/11/07 NN added local variables initialization */ 381 unsigned short usByteSize = 0; 382 unsigned short usBitIndex = 0; 383 signed short usByteIndex = 0; 384 unsigned char ucByte = 0; 385 unsigned char ucFlipByte = 0; 386 387 if (a_iDataSize % 8) { 388 /* 09/11/07 NN Type cast mismatch variables */ 389 usByteSize = (unsigned short)(a_iDataSize / 8 + 1); 390 } else { 391 /* 09/11/07 NN Type cast mismatch variables */ 392 usByteSize = (unsigned short)(a_iDataSize / 8); 393 } 394 puts("("); 395 /* 09/11/07 NN Type cast mismatch variables */ 396 for (usByteIndex = (signed short)(usByteSize - 1); 397 usByteIndex >= 0; usByteIndex--) { 398 ucByte = a_pucData[usByteIndex]; 399 ucFlipByte = 0x00; 400 401 /* 402 * 403 * Flip each byte. 404 * 405 */ 406 407 for (usBitIndex = 0; usBitIndex < 8; usBitIndex++) { 408 ucFlipByte <<= 1; 409 if (ucByte & 0x1) { 410 ucFlipByte |= 0x1; 411 } 412 413 ucByte >>= 1; 414 } 415 416 /* 417 * 418 * Print the flipped byte. 419 * 420 */ 421 422 printf("%.02X", ucFlipByte); 423 if ((usByteSize - usByteIndex) % 40 == 39) { 424 puts("\n\t\t"); 425 } 426 if (usByteIndex < 0) 427 break; 428 } 429 puts(")"); 430 } 431 #endif /* DEBUG */ 432 433 void ispVMMemManager(signed char cTarget, unsigned short usSize) 434 { 435 switch (cTarget) { 436 case XTDI: 437 case TDI: 438 if (g_pucInData != NULL) { 439 if (previous_size == usSize) {/*memory exist*/ 440 break; 441 } else { 442 free(g_pucInData); 443 g_pucInData = NULL; 444 } 445 } 446 g_pucInData = (unsigned char *) malloc(usSize / 8 + 2); 447 previous_size = usSize; 448 case XTDO: 449 case TDO: 450 if (g_pucOutData != NULL) { 451 if (previous_size == usSize) { /*already exist*/ 452 break; 453 } else { 454 free(g_pucOutData); 455 g_pucOutData = NULL; 456 } 457 } 458 g_pucOutData = (unsigned char *) malloc(usSize / 8 + 2); 459 previous_size = usSize; 460 break; 461 case MASK: 462 if (g_pucOutMaskData != NULL) { 463 if (previous_size == usSize) {/*already allocated*/ 464 break; 465 } else { 466 free(g_pucOutMaskData); 467 g_pucOutMaskData = NULL; 468 } 469 } 470 g_pucOutMaskData = (unsigned char *) malloc(usSize / 8 + 2); 471 previous_size = usSize; 472 break; 473 case HIR: 474 if (g_pucHIRData != NULL) { 475 free(g_pucHIRData); 476 g_pucHIRData = NULL; 477 } 478 g_pucHIRData = (unsigned char *) malloc(usSize / 8 + 2); 479 break; 480 case TIR: 481 if (g_pucTIRData != NULL) { 482 free(g_pucTIRData); 483 g_pucTIRData = NULL; 484 } 485 g_pucTIRData = (unsigned char *) malloc(usSize / 8 + 2); 486 break; 487 case HDR: 488 if (g_pucHDRData != NULL) { 489 free(g_pucHDRData); 490 g_pucHDRData = NULL; 491 } 492 g_pucHDRData = (unsigned char *) malloc(usSize / 8 + 2); 493 break; 494 case TDR: 495 if (g_pucTDRData != NULL) { 496 free(g_pucTDRData); 497 g_pucTDRData = NULL; 498 } 499 g_pucTDRData = (unsigned char *) malloc(usSize / 8 + 2); 500 break; 501 case HEAP: 502 if (g_pucHeapMemory != NULL) { 503 free(g_pucHeapMemory); 504 g_pucHeapMemory = NULL; 505 } 506 g_pucHeapMemory = (unsigned char *) malloc(usSize + 2); 507 break; 508 case DMASK: 509 if (g_pucOutDMaskData != NULL) { 510 if (previous_size == usSize) { /*already allocated*/ 511 break; 512 } else { 513 free(g_pucOutDMaskData); 514 g_pucOutDMaskData = NULL; 515 } 516 } 517 g_pucOutDMaskData = (unsigned char *) malloc(usSize / 8 + 2); 518 previous_size = usSize; 519 break; 520 case LHEAP: 521 if (g_pucIntelBuffer != NULL) { 522 free(g_pucIntelBuffer); 523 g_pucIntelBuffer = NULL; 524 } 525 g_pucIntelBuffer = (unsigned char *) malloc(usSize + 2); 526 break; 527 case LVDS: 528 if (g_pLVDSList != NULL) { 529 free(g_pLVDSList); 530 g_pLVDSList = NULL; 531 } 532 g_pLVDSList = (LVDSPair *) malloc(usSize * sizeof(LVDSPair)); 533 if (g_pLVDSList) 534 memset(g_pLVDSList, 0, usSize * sizeof(LVDSPair)); 535 break; 536 default: 537 return; 538 } 539 } 540 541 void ispVMFreeMem(void) 542 { 543 if (g_pucHeapMemory != NULL) { 544 free(g_pucHeapMemory); 545 g_pucHeapMemory = NULL; 546 } 547 548 if (g_pucOutMaskData != NULL) { 549 free(g_pucOutMaskData); 550 g_pucOutMaskData = NULL; 551 } 552 553 if (g_pucInData != NULL) { 554 free(g_pucInData); 555 g_pucInData = NULL; 556 } 557 558 if (g_pucOutData != NULL) { 559 free(g_pucOutData); 560 g_pucOutData = NULL; 561 } 562 563 if (g_pucHIRData != NULL) { 564 free(g_pucHIRData); 565 g_pucHIRData = NULL; 566 } 567 568 if (g_pucTIRData != NULL) { 569 free(g_pucTIRData); 570 g_pucTIRData = NULL; 571 } 572 573 if (g_pucHDRData != NULL) { 574 free(g_pucHDRData); 575 g_pucHDRData = NULL; 576 } 577 578 if (g_pucTDRData != NULL) { 579 free(g_pucTDRData); 580 g_pucTDRData = NULL; 581 } 582 583 if (g_pucOutDMaskData != NULL) { 584 free(g_pucOutDMaskData); 585 g_pucOutDMaskData = NULL; 586 } 587 588 if (g_pucIntelBuffer != NULL) { 589 free(g_pucIntelBuffer); 590 g_pucIntelBuffer = NULL; 591 } 592 593 if (g_pLVDSList != NULL) { 594 free(g_pLVDSList); 595 g_pLVDSList = NULL; 596 } 597 } 598 599 600 /* 601 * 602 * ispVMDataSize 603 * 604 * Returns a VME-encoded number, usually used to indicate the 605 * bit length of an SIR/SDR command. 606 * 607 */ 608 609 long int ispVMDataSize() 610 { 611 /* 09/11/07 NN added local variables initialization */ 612 long int iSize = 0; 613 signed char cCurrentByte = 0; 614 signed char cIndex = 0; 615 cIndex = 0; 616 while ((cCurrentByte = GetByte()) & 0x80) { 617 iSize |= ((long int) (cCurrentByte & 0x7F)) << cIndex; 618 cIndex += 7; 619 } 620 iSize |= ((long int) (cCurrentByte & 0x7F)) << cIndex; 621 return iSize; 622 } 623 624 /* 625 * 626 * ispVMCode 627 * 628 * This is the heart of the embedded engine. All the high-level opcodes 629 * are extracted here. Once they have been identified, then it 630 * will call other functions to handle the processing. 631 * 632 */ 633 634 signed char ispVMCode() 635 { 636 /* 09/11/07 NN added local variables initialization */ 637 unsigned short iRepeatSize = 0; 638 signed char cOpcode = 0; 639 signed char cRetCode = 0; 640 unsigned char ucState = 0; 641 unsigned short usDelay = 0; 642 unsigned short usToggle = 0; 643 unsigned char usByte = 0; 644 645 /* 646 * 647 * Check the compression flag only if this is the first time 648 * this function is entered. Do not check the compression flag if 649 * it is being called recursively from other functions within 650 * the embedded engine. 651 * 652 */ 653 654 if (!(g_usDataType & LHEAP_IN) && !(g_usDataType & HEAP_IN)) { 655 usByte = GetByte(); 656 if (usByte == 0xf1) { 657 g_usDataType |= COMPRESS; 658 } else if (usByte == 0xf2) { 659 g_usDataType &= ~COMPRESS; 660 } else { 661 return VME_INVALID_FILE; 662 } 663 } 664 665 /* 666 * 667 * Begin looping through all the VME opcodes. 668 * 669 */ 670 671 while ((cOpcode = GetByte()) >= 0) { 672 673 switch (cOpcode) { 674 case STATE: 675 676 /* 677 * Step the JTAG state machine. 678 */ 679 680 ucState = GetByte(); 681 682 /* 683 * Step the JTAG state machine to DRCAPTURE 684 * to support Looping. 685 */ 686 687 if ((g_usDataType & LHEAP_IN) && 688 (ucState == DRPAUSE) && 689 (g_cCurrentJTAGState == ucState)) { 690 ispVMStateMachine(DRCAPTURE); 691 } 692 693 ispVMStateMachine(ucState); 694 695 #ifdef DEBUG 696 if (g_usDataType & LHEAP_IN) { 697 debug("LDELAY %s ", GetState(ucState)); 698 } else { 699 debug("STATE %s;\n", GetState(ucState)); 700 } 701 #endif /* DEBUG */ 702 break; 703 case SIR: 704 case SDR: 705 case XSDR: 706 707 #ifdef DEBUG 708 switch (cOpcode) { 709 case SIR: 710 puts("SIR "); 711 break; 712 case SDR: 713 case XSDR: 714 if (g_usDataType & LHEAP_IN) { 715 puts("LSDR "); 716 } else { 717 puts("SDR "); 718 } 719 break; 720 } 721 #endif /* DEBUG */ 722 /* 723 * 724 * Shift in data into the device. 725 * 726 */ 727 728 cRetCode = ispVMShift(cOpcode); 729 if (cRetCode != 0) { 730 return cRetCode; 731 } 732 break; 733 case WAIT: 734 735 /* 736 * 737 * Observe delay. 738 * 739 */ 740 741 /* 09/11/07 NN Type cast mismatch variables */ 742 usDelay = (unsigned short) ispVMDataSize(); 743 ispVMDelay(usDelay); 744 745 #ifdef DEBUG 746 if (usDelay & 0x8000) { 747 748 /* 749 * Since MSB is set, the delay time must be 750 * decoded to millisecond. The SVF2VME encodes 751 * the MSB to represent millisecond. 752 */ 753 754 usDelay &= ~0x8000; 755 if (g_usDataType & LHEAP_IN) { 756 printf("%.2E SEC;\n", 757 (float) usDelay / 1000); 758 } else { 759 printf("RUNTEST %.2E SEC;\n", 760 (float) usDelay / 1000); 761 } 762 } else { 763 /* 764 * Since MSB is not set, the delay time 765 * is given as microseconds. 766 */ 767 768 if (g_usDataType & LHEAP_IN) { 769 printf("%.2E SEC;\n", 770 (float) usDelay / 1000000); 771 } else { 772 printf("RUNTEST %.2E SEC;\n", 773 (float) usDelay / 1000000); 774 } 775 } 776 #endif /* DEBUG */ 777 break; 778 case TCK: 779 780 /* 781 * Issue clock toggles. 782 */ 783 784 /* 09/11/07 NN Type cast mismatch variables */ 785 usToggle = (unsigned short) ispVMDataSize(); 786 ispVMClocks(usToggle); 787 788 #ifdef DEBUG 789 printf("RUNTEST %d TCK;\n", usToggle); 790 #endif /* DEBUG */ 791 break; 792 case ENDDR: 793 794 /* 795 * 796 * Set the ENDDR. 797 * 798 */ 799 800 g_ucEndDR = GetByte(); 801 802 #ifdef DEBUG 803 printf("ENDDR %s;\n", GetState(g_ucEndDR)); 804 #endif /* DEBUG */ 805 break; 806 case ENDIR: 807 808 /* 809 * 810 * Set the ENDIR. 811 * 812 */ 813 814 g_ucEndIR = GetByte(); 815 816 #ifdef DEBUG 817 printf("ENDIR %s;\n", GetState(g_ucEndIR)); 818 #endif /* DEBUG */ 819 break; 820 case HIR: 821 case TIR: 822 case HDR: 823 case TDR: 824 825 #ifdef DEBUG 826 switch (cOpcode) { 827 case HIR: 828 puts("HIR "); 829 break; 830 case TIR: 831 puts("TIR "); 832 break; 833 case HDR: 834 puts("HDR "); 835 break; 836 case TDR: 837 puts("TDR "); 838 break; 839 } 840 #endif /* DEBUG */ 841 /* 842 * Set the header/trailer of the device in order 843 * to bypass 844 * successfully. 845 */ 846 847 cRetCode = ispVMAmble(cOpcode); 848 if (cRetCode != 0) { 849 return cRetCode; 850 } 851 852 #ifdef DEBUG 853 puts(";\n"); 854 #endif /* DEBUG */ 855 break; 856 case MEM: 857 858 /* 859 * The maximum RAM required to support 860 * processing one row of the VME file. 861 */ 862 863 /* 09/11/07 NN Type cast mismatch variables */ 864 g_usMaxSize = (unsigned short) ispVMDataSize(); 865 866 #ifdef DEBUG 867 printf("// MEMSIZE %d\n", g_usMaxSize); 868 #endif /* DEBUG */ 869 break; 870 case VENDOR: 871 872 /* 873 * 874 * Set the VENDOR type. 875 * 876 */ 877 878 cOpcode = GetByte(); 879 switch (cOpcode) { 880 case LATTICE: 881 #ifdef DEBUG 882 puts("// VENDOR LATTICE\n"); 883 #endif /* DEBUG */ 884 g_cVendor = LATTICE; 885 break; 886 case ALTERA: 887 #ifdef DEBUG 888 puts("// VENDOR ALTERA\n"); 889 #endif /* DEBUG */ 890 g_cVendor = ALTERA; 891 break; 892 case XILINX: 893 #ifdef DEBUG 894 puts("// VENDOR XILINX\n"); 895 #endif /* DEBUG */ 896 g_cVendor = XILINX; 897 break; 898 default: 899 break; 900 } 901 break; 902 case SETFLOW: 903 904 /* 905 * Set the flow control. Flow control determines 906 * the personality of the embedded engine. 907 */ 908 909 /* 09/11/07 NN Type cast mismatch variables */ 910 g_usFlowControl |= (unsigned short) ispVMDataSize(); 911 break; 912 case RESETFLOW: 913 914 /* 915 * 916 * Unset the flow control. 917 * 918 */ 919 920 /* 09/11/07 NN Type cast mismatch variables */ 921 g_usFlowControl &= (unsigned short) ~(ispVMDataSize()); 922 break; 923 case HEAP: 924 925 /* 926 * 927 * Allocate heap size to store loops. 928 * 929 */ 930 931 cRetCode = GetByte(); 932 if (cRetCode != SECUREHEAP) { 933 return VME_INVALID_FILE; 934 } 935 /* 09/11/07 NN Type cast mismatch variables */ 936 g_iHEAPSize = (unsigned short) ispVMDataSize(); 937 938 /* 939 * Store the maximum size of the HEAP buffer. 940 * Used to convert VME to HEX. 941 */ 942 943 if (g_iHEAPSize > g_usHeapSize) { 944 g_usHeapSize = g_iHEAPSize; 945 } 946 947 ispVMMemManager(HEAP, (unsigned short) g_iHEAPSize); 948 break; 949 case REPEAT: 950 951 /* 952 * 953 * Execute loops. 954 * 955 */ 956 957 g_usRepeatLoops = 0; 958 959 /* 09/11/07 NN Type cast mismatch variables */ 960 iRepeatSize = (unsigned short) ispVMDataSize(); 961 962 cRetCode = ispVMLoop((unsigned short) iRepeatSize); 963 if (cRetCode != 0) { 964 return cRetCode; 965 } 966 break; 967 case ENDLOOP: 968 969 /* 970 * 971 * Exit point from processing loops. 972 * 973 */ 974 975 return cRetCode; 976 case ENDVME: 977 978 /* 979 * The only valid exit point that indicates 980 * end of programming. 981 */ 982 983 return cRetCode; 984 case SHR: 985 986 /* 987 * 988 * Right-shift address. 989 * 990 */ 991 992 g_usFlowControl |= SHIFTRIGHT; 993 994 /* 09/11/07 NN Type cast mismatch variables */ 995 g_usShiftValue = (unsigned short) (g_usRepeatLoops * 996 (unsigned short)GetByte()); 997 break; 998 case SHL: 999 1000 /* 1001 * Left-shift address. 1002 */ 1003 1004 g_usFlowControl |= SHIFTLEFT; 1005 1006 /* 09/11/07 NN Type cast mismatch variables */ 1007 g_usShiftValue = (unsigned short) (g_usRepeatLoops * 1008 (unsigned short)GetByte()); 1009 break; 1010 case FREQUENCY: 1011 1012 /* 1013 * 1014 * Set the frequency. 1015 * 1016 */ 1017 1018 /* 09/11/07 NN Type cast mismatch variables */ 1019 g_iFrequency = (int) (ispVMDataSize() / 1000); 1020 if (g_iFrequency == 1) 1021 g_iFrequency = 1000; 1022 1023 #ifdef DEBUG 1024 printf("FREQUENCY %.2E HZ;\n", 1025 (float) g_iFrequency * 1000); 1026 #endif /* DEBUG */ 1027 break; 1028 case LCOUNT: 1029 1030 /* 1031 * 1032 * Process LCOUNT command. 1033 * 1034 */ 1035 1036 cRetCode = ispVMLCOUNT((unsigned short)ispVMDataSize()); 1037 if (cRetCode != 0) { 1038 return cRetCode; 1039 } 1040 break; 1041 case VUES: 1042 1043 /* 1044 * 1045 * Set the flow control to verify USERCODE. 1046 * 1047 */ 1048 1049 g_usFlowControl |= VERIFYUES; 1050 break; 1051 case COMMENT: 1052 1053 /* 1054 * 1055 * Display comment. 1056 * 1057 */ 1058 1059 ispVMComment((unsigned short) ispVMDataSize()); 1060 break; 1061 case LVDS: 1062 1063 /* 1064 * 1065 * Process LVDS command. 1066 * 1067 */ 1068 1069 ispVMProcessLVDS((unsigned short) ispVMDataSize()); 1070 break; 1071 case HEADER: 1072 1073 /* 1074 * 1075 * Discard header. 1076 * 1077 */ 1078 1079 ispVMHeader((unsigned short) ispVMDataSize()); 1080 break; 1081 /* 03/14/06 Support Toggle ispENABLE signal*/ 1082 case ispEN: 1083 ucState = GetByte(); 1084 if ((ucState == ON) || (ucState == 0x01)) 1085 writePort(g_ucPinENABLE, 0x01); 1086 else 1087 writePort(g_ucPinENABLE, 0x00); 1088 ispVMDelay(1); 1089 break; 1090 /* 05/24/06 support Toggle TRST pin*/ 1091 case TRST: 1092 ucState = GetByte(); 1093 if (ucState == 0x01) 1094 writePort(g_ucPinTRST, 0x01); 1095 else 1096 writePort(g_ucPinTRST, 0x00); 1097 ispVMDelay(1); 1098 break; 1099 default: 1100 1101 /* 1102 * 1103 * Invalid opcode encountered. 1104 * 1105 */ 1106 1107 #ifdef DEBUG 1108 printf("\nINVALID OPCODE: 0x%.2X\n", cOpcode); 1109 #endif /* DEBUG */ 1110 1111 return VME_INVALID_FILE; 1112 } 1113 } 1114 1115 /* 1116 * 1117 * Invalid exit point. Processing the token 'ENDVME' is the only 1118 * valid way to exit the embedded engine. 1119 * 1120 */ 1121 1122 return VME_INVALID_FILE; 1123 } 1124 1125 /* 1126 * 1127 * ispVMDataCode 1128 * 1129 * Processes the TDI/TDO/MASK/DMASK etc of an SIR/SDR command. 1130 * 1131 */ 1132 1133 signed char ispVMDataCode() 1134 { 1135 /* 09/11/07 NN added local variables initialization */ 1136 signed char cDataByte = 0; 1137 signed char siDataSource = 0; /*source of data from file by default*/ 1138 1139 if (g_usDataType & HEAP_IN) { 1140 siDataSource = 1; /*the source of data from memory*/ 1141 } 1142 1143 /* 1144 * 1145 * Clear the data type register. 1146 * 1147 **/ 1148 1149 g_usDataType &= ~(MASK_DATA + TDI_DATA + 1150 TDO_DATA + DMASK_DATA + CMASK_DATA); 1151 1152 /* 1153 * Iterate through SIR/SDR command and look for TDI, 1154 * TDO, MASK, etc. 1155 */ 1156 1157 while ((cDataByte = GetByte()) >= 0) { 1158 ispVMMemManager(cDataByte, g_usMaxSize); 1159 switch (cDataByte) { 1160 case TDI: 1161 1162 /* 1163 * Store the maximum size of the TDI buffer. 1164 * Used to convert VME to HEX. 1165 */ 1166 1167 if (g_usiDataSize > g_usTDISize) { 1168 g_usTDISize = g_usiDataSize; 1169 } 1170 /* 1171 * Updated data type register to indicate that 1172 * TDI data is currently being used. Process the 1173 * data in the VME file into the TDI buffer. 1174 */ 1175 1176 g_usDataType |= TDI_DATA; 1177 ispVMData(g_pucInData); 1178 break; 1179 case XTDO: 1180 1181 /* 1182 * Store the maximum size of the TDO buffer. 1183 * Used to convert VME to HEX. 1184 */ 1185 1186 if (g_usiDataSize > g_usTDOSize) { 1187 g_usTDOSize = g_usiDataSize; 1188 } 1189 1190 /* 1191 * Updated data type register to indicate that 1192 * TDO data is currently being used. 1193 */ 1194 1195 g_usDataType |= TDO_DATA; 1196 break; 1197 case TDO: 1198 1199 /* 1200 * Store the maximum size of the TDO buffer. 1201 * Used to convert VME to HEX. 1202 */ 1203 1204 if (g_usiDataSize > g_usTDOSize) { 1205 g_usTDOSize = g_usiDataSize; 1206 } 1207 1208 /* 1209 * Updated data type register to indicate 1210 * that TDO data is currently being used. 1211 * Process the data in the VME file into the 1212 * TDO buffer. 1213 */ 1214 1215 g_usDataType |= TDO_DATA; 1216 ispVMData(g_pucOutData); 1217 break; 1218 case MASK: 1219 1220 /* 1221 * Store the maximum size of the MASK buffer. 1222 * Used to convert VME to HEX. 1223 */ 1224 1225 if (g_usiDataSize > g_usMASKSize) { 1226 g_usMASKSize = g_usiDataSize; 1227 } 1228 1229 /* 1230 * Updated data type register to indicate that 1231 * MASK data is currently being used. Process 1232 * the data in the VME file into the MASK buffer 1233 */ 1234 1235 g_usDataType |= MASK_DATA; 1236 ispVMData(g_pucOutMaskData); 1237 break; 1238 case DMASK: 1239 1240 /* 1241 * Store the maximum size of the DMASK buffer. 1242 * Used to convert VME to HEX. 1243 */ 1244 1245 if (g_usiDataSize > g_usDMASKSize) { 1246 g_usDMASKSize = g_usiDataSize; 1247 } 1248 1249 /* 1250 * Updated data type register to indicate that 1251 * DMASK data is currently being used. Process 1252 * the data in the VME file into the DMASK 1253 * buffer. 1254 */ 1255 1256 g_usDataType |= DMASK_DATA; 1257 ispVMData(g_pucOutDMaskData); 1258 break; 1259 case CMASK: 1260 1261 /* 1262 * Updated data type register to indicate that 1263 * MASK data is currently being used. Process 1264 * the data in the VME file into the MASK buffer 1265 */ 1266 1267 g_usDataType |= CMASK_DATA; 1268 ispVMData(g_pucOutMaskData); 1269 break; 1270 case CONTINUE: 1271 return 0; 1272 default: 1273 /* 1274 * Encountered invalid opcode. 1275 */ 1276 return VME_INVALID_FILE; 1277 } 1278 1279 switch (cDataByte) { 1280 case TDI: 1281 1282 /* 1283 * Left bit shift. Used when performing 1284 * algorithm looping. 1285 */ 1286 1287 if (g_usFlowControl & SHIFTLEFT) { 1288 ispVMBitShift(SHL, g_usShiftValue); 1289 g_usFlowControl &= ~SHIFTLEFT; 1290 } 1291 1292 /* 1293 * Right bit shift. Used when performing 1294 * algorithm looping. 1295 */ 1296 1297 if (g_usFlowControl & SHIFTRIGHT) { 1298 ispVMBitShift(SHR, g_usShiftValue); 1299 g_usFlowControl &= ~SHIFTRIGHT; 1300 } 1301 default: 1302 break; 1303 } 1304 1305 if (siDataSource) { 1306 g_usDataType |= HEAP_IN; /*restore from memory*/ 1307 } 1308 } 1309 1310 if (siDataSource) { /*fetch data from heap memory upon return*/ 1311 g_usDataType |= HEAP_IN; 1312 } 1313 1314 if (cDataByte < 0) { 1315 1316 /* 1317 * Encountered invalid opcode. 1318 */ 1319 1320 return VME_INVALID_FILE; 1321 } else { 1322 return 0; 1323 } 1324 } 1325 1326 /* 1327 * 1328 * ispVMData 1329 * Extract one row of data operand from the current data type opcode. Perform 1330 * the decompression if necessary. Extra RAM is not required for the 1331 * decompression process. The decompression scheme employed in this module 1332 * is on row by row basis. The format of the data stream: 1333 * [compression code][compressed data stream] 1334 * 0x00 --No compression 1335 * 0x01 --Compress by 0x00. 1336 * Example: 1337 * Original stream: 0x000000000000000000000001 1338 * Compressed stream: 0x01000901 1339 * Detail: 0x01 is the code, 0x00 is the key, 1340 * 0x09 is the count of 0x00 bytes, 1341 * 0x01 is the uncompressed byte. 1342 * 0x02 --Compress by 0xFF. 1343 * Example: 1344 * Original stream: 0xFFFFFFFFFFFFFFFFFFFFFF01 1345 * Compressed stream: 0x02FF0901 1346 * Detail: 0x02 is the code, 0xFF is the key, 1347 * 0x09 is the count of 0xFF bytes, 1348 * 0x01 is the uncompressed byte. 1349 * 0x03 1350 * : : 1351 * 0xFE -- Compress by nibble blocks. 1352 * Example: 1353 * Original stream: 0x84210842108421084210 1354 * Compressed stream: 0x0584210 1355 * Detail: 0x05 is the code, means 5 nibbles block. 1356 * 0x84210 is the 5 nibble blocks. 1357 * The whole row is 80 bits given by g_usiDataSize. 1358 * The number of times the block repeat itself 1359 * is found by g_usiDataSize/(4*0x05) which is 4. 1360 * 0xFF -- Compress by the most frequently happen byte. 1361 * Example: 1362 * Original stream: 0x04020401030904040404 1363 * Compressed stream: 0xFF04(0,1,0x02,0,1,0x01,1,0x03,1,0x09,0,0,0) 1364 * or: 0xFF044090181C240 1365 * Detail: 0xFF is the code, 0x04 is the key. 1366 * a bit of 0 represent the key shall be put into 1367 * the current bit position and a bit of 1 1368 * represent copying the next of 8 bits of data 1369 * in. 1370 * 1371 */ 1372 1373 void ispVMData(unsigned char *ByteData) 1374 { 1375 /* 09/11/07 NN added local variables initialization */ 1376 unsigned short size = 0; 1377 unsigned short i, j, m, getData = 0; 1378 unsigned char cDataByte = 0; 1379 unsigned char compress = 0; 1380 unsigned short FFcount = 0; 1381 unsigned char compr_char = 0xFF; 1382 unsigned short index = 0; 1383 signed char compression = 0; 1384 1385 /*convert number in bits to bytes*/ 1386 if (g_usiDataSize % 8 > 0) { 1387 /* 09/11/07 NN Type cast mismatch variables */ 1388 size = (unsigned short)(g_usiDataSize / 8 + 1); 1389 } else { 1390 /* 09/11/07 NN Type cast mismatch variables */ 1391 size = (unsigned short)(g_usiDataSize / 8); 1392 } 1393 1394 /* 1395 * If there is compression, then check if compress by key 1396 * of 0x00 or 0xFF or by other keys or by nibble blocks 1397 */ 1398 1399 if (g_usDataType & COMPRESS) { 1400 compression = 1; 1401 compress = GetByte(); 1402 if ((compress == VAR) && (g_usDataType & HEAP_IN)) { 1403 getData = 1; 1404 g_usDataType &= ~(HEAP_IN); 1405 compress = GetByte(); 1406 } 1407 1408 switch (compress) { 1409 case 0x00: 1410 /* No compression */ 1411 compression = 0; 1412 break; 1413 case 0x01: 1414 /* Compress by byte 0x00 */ 1415 compr_char = 0x00; 1416 break; 1417 case 0x02: 1418 /* Compress by byte 0xFF */ 1419 compr_char = 0xFF; 1420 break; 1421 case 0xFF: 1422 /* Huffman encoding */ 1423 compr_char = GetByte(); 1424 i = 8; 1425 for (index = 0; index < size; index++) { 1426 ByteData[index] = 0x00; 1427 if (i > 7) { 1428 cDataByte = GetByte(); 1429 i = 0; 1430 } 1431 if ((cDataByte << i++) & 0x80) 1432 m = 8; 1433 else { 1434 ByteData[index] = compr_char; 1435 m = 0; 1436 } 1437 1438 for (j = 0; j < m; j++) { 1439 if (i > 7) { 1440 cDataByte = GetByte(); 1441 i = 0; 1442 } 1443 ByteData[index] |= 1444 ((cDataByte << i++) & 0x80) >> j; 1445 } 1446 } 1447 size = 0; 1448 break; 1449 default: 1450 for (index = 0; index < size; index++) 1451 ByteData[index] = 0x00; 1452 for (index = 0; index < compress; index++) { 1453 if (index % 2 == 0) 1454 cDataByte = GetByte(); 1455 for (i = 0; i < size * 2 / compress; i++) { 1456 j = (unsigned short)(index + 1457 (i * (unsigned short)compress)); 1458 /*clear the nibble to zero first*/ 1459 if (j%2) { 1460 if (index % 2) 1461 ByteData[j/2] |= 1462 cDataByte & 0xF; 1463 else 1464 ByteData[j/2] |= 1465 cDataByte >> 4; 1466 } else { 1467 if (index % 2) 1468 ByteData[j/2] |= 1469 cDataByte << 4; 1470 else 1471 ByteData[j/2] |= 1472 cDataByte & 0xF0; 1473 } 1474 } 1475 } 1476 size = 0; 1477 break; 1478 } 1479 } 1480 1481 FFcount = 0; 1482 1483 /* Decompress by byte 0x00 or 0xFF */ 1484 for (index = 0; index < size; index++) { 1485 if (FFcount <= 0) { 1486 cDataByte = GetByte(); 1487 if ((cDataByte == VAR) && (g_usDataType&HEAP_IN) && 1488 !getData && !(g_usDataType&COMPRESS)) { 1489 getData = 1; 1490 g_usDataType &= ~(HEAP_IN); 1491 cDataByte = GetByte(); 1492 } 1493 ByteData[index] = cDataByte; 1494 if ((compression) && (cDataByte == compr_char)) 1495 /* 09/11/07 NN Type cast mismatch variables */ 1496 FFcount = (unsigned short) ispVMDataSize(); 1497 /*The number of 0xFF or 0x00 bytes*/ 1498 } else { 1499 FFcount--; /*Use up the 0xFF chain first*/ 1500 ByteData[index] = compr_char; 1501 } 1502 } 1503 1504 if (getData) { 1505 g_usDataType |= HEAP_IN; 1506 getData = 0; 1507 } 1508 } 1509 1510 /* 1511 * 1512 * ispVMShift 1513 * 1514 * Processes the SDR/XSDR/SIR commands. 1515 * 1516 */ 1517 1518 signed char ispVMShift(signed char a_cCode) 1519 { 1520 /* 09/11/07 NN added local variables initialization */ 1521 unsigned short iDataIndex = 0; 1522 unsigned short iReadLoop = 0; 1523 signed char cRetCode = 0; 1524 1525 cRetCode = 0; 1526 /* 09/11/07 NN Type cast mismatch variables */ 1527 g_usiDataSize = (unsigned short) ispVMDataSize(); 1528 1529 /*clear the flags first*/ 1530 g_usDataType &= ~(SIR_DATA + EXPRESS + SDR_DATA); 1531 switch (a_cCode) { 1532 case SIR: 1533 g_usDataType |= SIR_DATA; 1534 /* 1535 * 1/15/04 If performing cascading, then go directly to SHIFTIR. 1536 * Else, go to IRPAUSE before going to SHIFTIR 1537 */ 1538 if (g_usFlowControl & CASCADE) { 1539 ispVMStateMachine(SHIFTIR); 1540 } else { 1541 ispVMStateMachine(IRPAUSE); 1542 ispVMStateMachine(SHIFTIR); 1543 if (g_usHeadIR > 0) { 1544 ispVMBypass(HIR, g_usHeadIR); 1545 sclock(); 1546 } 1547 } 1548 break; 1549 case XSDR: 1550 g_usDataType |= EXPRESS; /*mark simultaneous in and out*/ 1551 case SDR: 1552 g_usDataType |= SDR_DATA; 1553 /* 1554 * 1/15/04 If already in SHIFTDR, then do not move state or 1555 * shift in header. This would imply that the previously 1556 * shifted frame was a cascaded frame. 1557 */ 1558 if (g_cCurrentJTAGState != SHIFTDR) { 1559 /* 1560 * 1/15/04 If performing cascading, then go directly 1561 * to SHIFTDR. Else, go to DRPAUSE before going 1562 * to SHIFTDR 1563 */ 1564 if (g_usFlowControl & CASCADE) { 1565 if (g_cCurrentJTAGState == DRPAUSE) { 1566 ispVMStateMachine(SHIFTDR); 1567 /* 1568 * 1/15/04 If cascade flag has been seat 1569 * and the current state is DRPAUSE, 1570 * this implies that the first cascaded 1571 * frame is about to be shifted in. The 1572 * header must be shifted prior to 1573 * shifting the first cascaded frame. 1574 */ 1575 if (g_usHeadDR > 0) { 1576 ispVMBypass(HDR, g_usHeadDR); 1577 sclock(); 1578 } 1579 } else { 1580 ispVMStateMachine(SHIFTDR); 1581 } 1582 } else { 1583 ispVMStateMachine(DRPAUSE); 1584 ispVMStateMachine(SHIFTDR); 1585 if (g_usHeadDR > 0) { 1586 ispVMBypass(HDR, g_usHeadDR); 1587 sclock(); 1588 } 1589 } 1590 } 1591 break; 1592 default: 1593 return VME_INVALID_FILE; 1594 } 1595 1596 cRetCode = ispVMDataCode(); 1597 1598 if (cRetCode != 0) { 1599 return VME_INVALID_FILE; 1600 } 1601 1602 #ifdef DEBUG 1603 printf("%d ", g_usiDataSize); 1604 1605 if (g_usDataType & TDI_DATA) { 1606 puts("TDI "); 1607 PrintData(g_usiDataSize, g_pucInData); 1608 } 1609 1610 if (g_usDataType & TDO_DATA) { 1611 puts("\n\t\tTDO "); 1612 PrintData(g_usiDataSize, g_pucOutData); 1613 } 1614 1615 if (g_usDataType & MASK_DATA) { 1616 puts("\n\t\tMASK "); 1617 PrintData(g_usiDataSize, g_pucOutMaskData); 1618 } 1619 1620 if (g_usDataType & DMASK_DATA) { 1621 puts("\n\t\tDMASK "); 1622 PrintData(g_usiDataSize, g_pucOutDMaskData); 1623 } 1624 1625 puts(";\n"); 1626 #endif /* DEBUG */ 1627 1628 if (g_usDataType & TDO_DATA || g_usDataType & DMASK_DATA) { 1629 if (g_usDataType & DMASK_DATA) { 1630 cRetCode = ispVMReadandSave(g_usiDataSize); 1631 if (!cRetCode) { 1632 if (g_usTailDR > 0) { 1633 sclock(); 1634 ispVMBypass(TDR, g_usTailDR); 1635 } 1636 ispVMStateMachine(DRPAUSE); 1637 ispVMStateMachine(SHIFTDR); 1638 if (g_usHeadDR > 0) { 1639 ispVMBypass(HDR, g_usHeadDR); 1640 sclock(); 1641 } 1642 for (iDataIndex = 0; 1643 iDataIndex < g_usiDataSize / 8 + 1; 1644 iDataIndex++) 1645 g_pucInData[iDataIndex] = 1646 g_pucOutData[iDataIndex]; 1647 g_usDataType &= ~(TDO_DATA + DMASK_DATA); 1648 cRetCode = ispVMSend(g_usiDataSize); 1649 } 1650 } else { 1651 cRetCode = ispVMRead(g_usiDataSize); 1652 if (cRetCode == -1 && g_cVendor == XILINX) { 1653 for (iReadLoop = 0; iReadLoop < 30; 1654 iReadLoop++) { 1655 cRetCode = ispVMRead(g_usiDataSize); 1656 if (!cRetCode) { 1657 break; 1658 } else { 1659 /* Always DRPAUSE */ 1660 ispVMStateMachine(DRPAUSE); 1661 /* 1662 * Bypass other devices 1663 * when appropriate 1664 */ 1665 ispVMBypass(TDR, g_usTailDR); 1666 ispVMStateMachine(g_ucEndDR); 1667 ispVMStateMachine(IDLE); 1668 ispVMDelay(1000); 1669 } 1670 } 1671 } 1672 } 1673 } else { /*TDI only*/ 1674 cRetCode = ispVMSend(g_usiDataSize); 1675 } 1676 1677 /*transfer the input data to the output buffer for the next verify*/ 1678 if ((g_usDataType & EXPRESS) || (a_cCode == SDR)) { 1679 if (g_pucOutData) { 1680 for (iDataIndex = 0; iDataIndex < g_usiDataSize / 8 + 1; 1681 iDataIndex++) 1682 g_pucOutData[iDataIndex] = 1683 g_pucInData[iDataIndex]; 1684 } 1685 } 1686 1687 switch (a_cCode) { 1688 case SIR: 1689 /* 1/15/04 If not performing cascading, then shift ENDIR */ 1690 if (!(g_usFlowControl & CASCADE)) { 1691 if (g_usTailIR > 0) { 1692 sclock(); 1693 ispVMBypass(TIR, g_usTailIR); 1694 } 1695 ispVMStateMachine(g_ucEndIR); 1696 } 1697 break; 1698 case XSDR: 1699 case SDR: 1700 /* 1/15/04 If not performing cascading, then shift ENDDR */ 1701 if (!(g_usFlowControl & CASCADE)) { 1702 if (g_usTailDR > 0) { 1703 sclock(); 1704 ispVMBypass(TDR, g_usTailDR); 1705 } 1706 ispVMStateMachine(g_ucEndDR); 1707 } 1708 break; 1709 default: 1710 break; 1711 } 1712 1713 return cRetCode; 1714 } 1715 1716 /* 1717 * 1718 * ispVMAmble 1719 * 1720 * This routine is to extract Header and Trailer parameter for SIR and 1721 * SDR operations. 1722 * 1723 * The Header and Trailer parameter are the pre-amble and post-amble bit 1724 * stream need to be shifted into TDI or out of TDO of the devices. Mostly 1725 * is for the purpose of bypassing the leading or trailing devices. ispVM 1726 * supports only shifting data into TDI to bypass the devices. 1727 * 1728 * For a single device, the header and trailer parameters are all set to 0 1729 * as default by ispVM. If it is for multiple devices, the header and trailer 1730 * value will change as specified by the VME file. 1731 * 1732 */ 1733 1734 signed char ispVMAmble(signed char Code) 1735 { 1736 signed char compress = 0; 1737 /* 09/11/07 NN Type cast mismatch variables */ 1738 g_usiDataSize = (unsigned short)ispVMDataSize(); 1739 1740 #ifdef DEBUG 1741 printf("%d", g_usiDataSize); 1742 #endif /* DEBUG */ 1743 1744 if (g_usiDataSize) { 1745 1746 /* 1747 * Discard the TDI byte and set the compression bit in the data 1748 * type register to false if compression is set because TDI data 1749 * after HIR/HDR/TIR/TDR is not compressed. 1750 */ 1751 1752 GetByte(); 1753 if (g_usDataType & COMPRESS) { 1754 g_usDataType &= ~(COMPRESS); 1755 compress = 1; 1756 } 1757 } 1758 1759 switch (Code) { 1760 case HIR: 1761 1762 /* 1763 * Store the maximum size of the HIR buffer. 1764 * Used to convert VME to HEX. 1765 */ 1766 1767 if (g_usiDataSize > g_usHIRSize) { 1768 g_usHIRSize = g_usiDataSize; 1769 } 1770 1771 /* 1772 * Assign the HIR value and allocate memory. 1773 */ 1774 1775 g_usHeadIR = g_usiDataSize; 1776 if (g_usHeadIR) { 1777 ispVMMemManager(HIR, g_usHeadIR); 1778 ispVMData(g_pucHIRData); 1779 1780 #ifdef DEBUG 1781 puts(" TDI "); 1782 PrintData(g_usHeadIR, g_pucHIRData); 1783 #endif /* DEBUG */ 1784 } 1785 break; 1786 case TIR: 1787 1788 /* 1789 * Store the maximum size of the TIR buffer. 1790 * Used to convert VME to HEX. 1791 */ 1792 1793 if (g_usiDataSize > g_usTIRSize) { 1794 g_usTIRSize = g_usiDataSize; 1795 } 1796 1797 /* 1798 * Assign the TIR value and allocate memory. 1799 */ 1800 1801 g_usTailIR = g_usiDataSize; 1802 if (g_usTailIR) { 1803 ispVMMemManager(TIR, g_usTailIR); 1804 ispVMData(g_pucTIRData); 1805 1806 #ifdef DEBUG 1807 puts(" TDI "); 1808 PrintData(g_usTailIR, g_pucTIRData); 1809 #endif /* DEBUG */ 1810 } 1811 break; 1812 case HDR: 1813 1814 /* 1815 * Store the maximum size of the HDR buffer. 1816 * Used to convert VME to HEX. 1817 */ 1818 1819 if (g_usiDataSize > g_usHDRSize) { 1820 g_usHDRSize = g_usiDataSize; 1821 } 1822 1823 /* 1824 * Assign the HDR value and allocate memory. 1825 * 1826 */ 1827 1828 g_usHeadDR = g_usiDataSize; 1829 if (g_usHeadDR) { 1830 ispVMMemManager(HDR, g_usHeadDR); 1831 ispVMData(g_pucHDRData); 1832 1833 #ifdef DEBUG 1834 puts(" TDI "); 1835 PrintData(g_usHeadDR, g_pucHDRData); 1836 #endif /* DEBUG */ 1837 } 1838 break; 1839 case TDR: 1840 1841 /* 1842 * Store the maximum size of the TDR buffer. 1843 * Used to convert VME to HEX. 1844 */ 1845 1846 if (g_usiDataSize > g_usTDRSize) { 1847 g_usTDRSize = g_usiDataSize; 1848 } 1849 1850 /* 1851 * Assign the TDR value and allocate memory. 1852 * 1853 */ 1854 1855 g_usTailDR = g_usiDataSize; 1856 if (g_usTailDR) { 1857 ispVMMemManager(TDR, g_usTailDR); 1858 ispVMData(g_pucTDRData); 1859 1860 #ifdef DEBUG 1861 puts(" TDI "); 1862 PrintData(g_usTailDR, g_pucTDRData); 1863 #endif /* DEBUG */ 1864 } 1865 break; 1866 default: 1867 break; 1868 } 1869 1870 /* 1871 * 1872 * Re-enable compression if it was previously set. 1873 * 1874 **/ 1875 1876 if (compress) { 1877 g_usDataType |= COMPRESS; 1878 } 1879 1880 if (g_usiDataSize) { 1881 Code = GetByte(); 1882 if (Code == CONTINUE) { 1883 return 0; 1884 } else { 1885 1886 /* 1887 * Encountered invalid opcode. 1888 */ 1889 1890 return VME_INVALID_FILE; 1891 } 1892 } 1893 1894 return 0; 1895 } 1896 1897 /* 1898 * 1899 * ispVMLoop 1900 * 1901 * Perform the function call upon by the REPEAT opcode. 1902 * Memory is to be allocated to store the entire loop from REPEAT to ENDLOOP. 1903 * After the loop is stored then execution begin. The REPEATLOOP flag is set 1904 * on the g_usFlowControl register to indicate the repeat loop is in session 1905 * and therefore fetch opcode from the memory instead of from the file. 1906 * 1907 */ 1908 1909 signed char ispVMLoop(unsigned short a_usLoopCount) 1910 { 1911 /* 09/11/07 NN added local variables initialization */ 1912 signed char cRetCode = 0; 1913 unsigned short iHeapIndex = 0; 1914 unsigned short iLoopIndex = 0; 1915 1916 g_usShiftValue = 0; 1917 for (iHeapIndex = 0; iHeapIndex < g_iHEAPSize; iHeapIndex++) { 1918 g_pucHeapMemory[iHeapIndex] = GetByte(); 1919 } 1920 1921 if (g_pucHeapMemory[iHeapIndex - 1] != ENDLOOP) { 1922 return VME_INVALID_FILE; 1923 } 1924 1925 g_usFlowControl |= REPEATLOOP; 1926 g_usDataType |= HEAP_IN; 1927 1928 for (iLoopIndex = 0; iLoopIndex < a_usLoopCount; iLoopIndex++) { 1929 g_iHeapCounter = 0; 1930 cRetCode = ispVMCode(); 1931 g_usRepeatLoops++; 1932 if (cRetCode < 0) { 1933 break; 1934 } 1935 } 1936 1937 g_usDataType &= ~(HEAP_IN); 1938 g_usFlowControl &= ~(REPEATLOOP); 1939 return cRetCode; 1940 } 1941 1942 /* 1943 * 1944 * ispVMBitShift 1945 * 1946 * Shift the TDI stream left or right by the number of bits. The data in 1947 * *g_pucInData is of the VME format, so the actual shifting is the reverse of 1948 * IEEE 1532 or SVF format. 1949 * 1950 */ 1951 1952 signed char ispVMBitShift(signed char mode, unsigned short bits) 1953 { 1954 /* 09/11/07 NN added local variables initialization */ 1955 unsigned short i = 0; 1956 unsigned short size = 0; 1957 unsigned short tmpbits = 0; 1958 1959 if (g_usiDataSize % 8 > 0) { 1960 /* 09/11/07 NN Type cast mismatch variables */ 1961 size = (unsigned short)(g_usiDataSize / 8 + 1); 1962 } else { 1963 /* 09/11/07 NN Type cast mismatch variables */ 1964 size = (unsigned short)(g_usiDataSize / 8); 1965 } 1966 1967 switch (mode) { 1968 case SHR: 1969 for (i = 0; i < size; i++) { 1970 if (g_pucInData[i] != 0) { 1971 tmpbits = bits; 1972 while (tmpbits > 0) { 1973 g_pucInData[i] <<= 1; 1974 if (g_pucInData[i] == 0) { 1975 i--; 1976 g_pucInData[i] = 1; 1977 } 1978 tmpbits--; 1979 } 1980 } 1981 } 1982 break; 1983 case SHL: 1984 for (i = 0; i < size; i++) { 1985 if (g_pucInData[i] != 0) { 1986 tmpbits = bits; 1987 while (tmpbits > 0) { 1988 g_pucInData[i] >>= 1; 1989 if (g_pucInData[i] == 0) { 1990 i--; 1991 g_pucInData[i] = 8; 1992 } 1993 tmpbits--; 1994 } 1995 } 1996 } 1997 break; 1998 default: 1999 return VME_INVALID_FILE; 2000 } 2001 2002 return 0; 2003 } 2004 2005 /* 2006 * 2007 * ispVMComment 2008 * 2009 * Displays the SVF comments. 2010 * 2011 */ 2012 2013 void ispVMComment(unsigned short a_usCommentSize) 2014 { 2015 char cCurByte = 0; 2016 for (; a_usCommentSize > 0; a_usCommentSize--) { 2017 /* 2018 * 2019 * Print character to the terminal. 2020 * 2021 **/ 2022 cCurByte = GetByte(); 2023 vme_out_char(cCurByte); 2024 } 2025 cCurByte = '\n'; 2026 vme_out_char(cCurByte); 2027 } 2028 2029 /* 2030 * 2031 * ispVMHeader 2032 * 2033 * Iterate the length of the header and discard it. 2034 * 2035 */ 2036 2037 void ispVMHeader(unsigned short a_usHeaderSize) 2038 { 2039 for (; a_usHeaderSize > 0; a_usHeaderSize--) { 2040 GetByte(); 2041 } 2042 } 2043 2044 /* 2045 * 2046 * ispVMCalculateCRC32 2047 * 2048 * Calculate the 32-bit CRC. 2049 * 2050 */ 2051 2052 void ispVMCalculateCRC32(unsigned char a_ucData) 2053 { 2054 /* 09/11/07 NN added local variables initialization */ 2055 unsigned char ucIndex = 0; 2056 unsigned char ucFlipData = 0; 2057 unsigned short usCRCTableEntry = 0; 2058 unsigned int crc_table[16] = { 2059 0x0000, 0xCC01, 0xD801, 2060 0x1400, 0xF001, 0x3C00, 2061 0x2800, 0xE401, 0xA001, 2062 0x6C00, 0x7800, 0xB401, 2063 0x5000, 0x9C01, 0x8801, 2064 0x4400 2065 }; 2066 2067 for (ucIndex = 0; ucIndex < 8; ucIndex++) { 2068 ucFlipData <<= 1; 2069 if (a_ucData & 0x01) { 2070 ucFlipData |= 0x01; 2071 } 2072 a_ucData >>= 1; 2073 } 2074 2075 /* 09/11/07 NN Type cast mismatch variables */ 2076 usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]); 2077 g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF); 2078 g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ 2079 usCRCTableEntry ^ crc_table[ucFlipData & 0xF]); 2080 usCRCTableEntry = (unsigned short)(crc_table[g_usCalculatedCRC & 0xF]); 2081 g_usCalculatedCRC = (unsigned short)((g_usCalculatedCRC >> 4) & 0x0FFF); 2082 g_usCalculatedCRC = (unsigned short)(g_usCalculatedCRC ^ 2083 usCRCTableEntry ^ crc_table[(ucFlipData >> 4) & 0xF]); 2084 } 2085 2086 /* 2087 * 2088 * ispVMLCOUNT 2089 * 2090 * Process the intelligent programming loops. 2091 * 2092 */ 2093 2094 signed char ispVMLCOUNT(unsigned short a_usCountSize) 2095 { 2096 unsigned short usContinue = 1; 2097 unsigned short usIntelBufferIndex = 0; 2098 unsigned short usCountIndex = 0; 2099 signed char cRetCode = 0; 2100 signed char cRepeatHeap = 0; 2101 signed char cOpcode = 0; 2102 unsigned char ucState = 0; 2103 unsigned short usDelay = 0; 2104 unsigned short usToggle = 0; 2105 2106 g_usIntelBufferSize = (unsigned short)ispVMDataSize(); 2107 2108 /* 2109 * Allocate memory for intel buffer. 2110 * 2111 */ 2112 2113 ispVMMemManager(LHEAP, g_usIntelBufferSize); 2114 2115 /* 2116 * Store the maximum size of the intelligent buffer. 2117 * Used to convert VME to HEX. 2118 */ 2119 2120 if (g_usIntelBufferSize > g_usLCOUNTSize) { 2121 g_usLCOUNTSize = g_usIntelBufferSize; 2122 } 2123 2124 /* 2125 * Copy intel data to the buffer. 2126 */ 2127 2128 for (usIntelBufferIndex = 0; usIntelBufferIndex < g_usIntelBufferSize; 2129 usIntelBufferIndex++) { 2130 g_pucIntelBuffer[usIntelBufferIndex] = GetByte(); 2131 } 2132 2133 /* 2134 * Set the data type register to get data from the intelligent 2135 * data buffer. 2136 */ 2137 2138 g_usDataType |= LHEAP_IN; 2139 2140 /* 2141 * 2142 * If the HEAP_IN flag is set, temporarily unset the flag so data will be 2143 * retrieved from the status buffer. 2144 * 2145 **/ 2146 2147 if (g_usDataType & HEAP_IN) { 2148 g_usDataType &= ~HEAP_IN; 2149 cRepeatHeap = 1; 2150 } 2151 2152 #ifdef DEBUG 2153 printf("LCOUNT %d;\n", a_usCountSize); 2154 #endif /* DEBUG */ 2155 2156 /* 2157 * Iterate through the intelligent programming command. 2158 */ 2159 2160 for (usCountIndex = 0; usCountIndex < a_usCountSize; usCountIndex++) { 2161 2162 /* 2163 * 2164 * Initialize the intel data index to 0 before each iteration. 2165 * 2166 **/ 2167 2168 g_usIntelDataIndex = 0; 2169 cOpcode = 0; 2170 ucState = 0; 2171 usDelay = 0; 2172 usToggle = 0; 2173 usContinue = 1; 2174 2175 /* 2176 * 2177 * Begin looping through all the VME opcodes. 2178 * 2179 */ 2180 /* 2181 * 4/1/09 Nguyen replaced the recursive function call codes on 2182 * the ispVMLCOUNT function 2183 * 2184 */ 2185 while (usContinue) { 2186 cOpcode = GetByte(); 2187 switch (cOpcode) { 2188 case HIR: 2189 case TIR: 2190 case HDR: 2191 case TDR: 2192 /* 2193 * Set the header/trailer of the device in order 2194 * to bypass successfully. 2195 */ 2196 2197 ispVMAmble(cOpcode); 2198 break; 2199 case STATE: 2200 2201 /* 2202 * Step the JTAG state machine. 2203 */ 2204 2205 ucState = GetByte(); 2206 /* 2207 * Step the JTAG state machine to DRCAPTURE 2208 * to support Looping. 2209 */ 2210 2211 if ((g_usDataType & LHEAP_IN) && 2212 (ucState == DRPAUSE) && 2213 (g_cCurrentJTAGState == ucState)) { 2214 ispVMStateMachine(DRCAPTURE); 2215 } 2216 ispVMStateMachine(ucState); 2217 #ifdef DEBUG 2218 printf("LDELAY %s ", GetState(ucState)); 2219 #endif /* DEBUG */ 2220 break; 2221 case SIR: 2222 #ifdef DEBUG 2223 printf("SIR "); 2224 #endif /* DEBUG */ 2225 /* 2226 * Shift in data into the device. 2227 */ 2228 2229 cRetCode = ispVMShift(cOpcode); 2230 break; 2231 case SDR: 2232 2233 #ifdef DEBUG 2234 printf("LSDR "); 2235 #endif /* DEBUG */ 2236 /* 2237 * Shift in data into the device. 2238 */ 2239 2240 cRetCode = ispVMShift(cOpcode); 2241 break; 2242 case WAIT: 2243 2244 /* 2245 * 2246 * Observe delay. 2247 * 2248 */ 2249 2250 usDelay = (unsigned short)ispVMDataSize(); 2251 ispVMDelay(usDelay); 2252 2253 #ifdef DEBUG 2254 if (usDelay & 0x8000) { 2255 2256 /* 2257 * Since MSB is set, the delay time must 2258 * be decoded to millisecond. The 2259 * SVF2VME encodes the MSB to represent 2260 * millisecond. 2261 */ 2262 2263 usDelay &= ~0x8000; 2264 printf("%.2E SEC;\n", 2265 (float) usDelay / 1000); 2266 } else { 2267 /* 2268 * Since MSB is not set, the delay time 2269 * is given as microseconds. 2270 */ 2271 2272 printf("%.2E SEC;\n", 2273 (float) usDelay / 1000000); 2274 } 2275 #endif /* DEBUG */ 2276 break; 2277 case TCK: 2278 2279 /* 2280 * Issue clock toggles. 2281 */ 2282 2283 usToggle = (unsigned short)ispVMDataSize(); 2284 ispVMClocks(usToggle); 2285 2286 #ifdef DEBUG 2287 printf("RUNTEST %d TCK;\n", usToggle); 2288 #endif /* DEBUG */ 2289 break; 2290 case ENDLOOP: 2291 2292 /* 2293 * Exit point from processing loops. 2294 */ 2295 usContinue = 0; 2296 break; 2297 2298 case COMMENT: 2299 2300 /* 2301 * Display comment. 2302 */ 2303 2304 ispVMComment((unsigned short) ispVMDataSize()); 2305 break; 2306 case ispEN: 2307 ucState = GetByte(); 2308 if ((ucState == ON) || (ucState == 0x01)) 2309 writePort(g_ucPinENABLE, 0x01); 2310 else 2311 writePort(g_ucPinENABLE, 0x00); 2312 ispVMDelay(1); 2313 break; 2314 case TRST: 2315 if (GetByte() == 0x01) 2316 writePort(g_ucPinTRST, 0x01); 2317 else 2318 writePort(g_ucPinTRST, 0x00); 2319 ispVMDelay(1); 2320 break; 2321 default: 2322 2323 /* 2324 * Invalid opcode encountered. 2325 */ 2326 2327 debug("\nINVALID OPCODE: 0x%.2X\n", cOpcode); 2328 2329 return VME_INVALID_FILE; 2330 } 2331 } 2332 if (cRetCode >= 0) { 2333 /* 2334 * Break if intelligent programming is successful. 2335 */ 2336 2337 break; 2338 } 2339 2340 } 2341 /* 2342 * If HEAP_IN flag was temporarily disabled, 2343 * re-enable it before exiting 2344 */ 2345 2346 if (cRepeatHeap) { 2347 g_usDataType |= HEAP_IN; 2348 } 2349 2350 /* 2351 * Set the data type register to not get data from the 2352 * intelligent data buffer. 2353 */ 2354 2355 g_usDataType &= ~LHEAP_IN; 2356 return cRetCode; 2357 } 2358 /* 2359 * 2360 * ispVMClocks 2361 * 2362 * Applies the specified number of pulses to TCK. 2363 * 2364 */ 2365 2366 void ispVMClocks(unsigned short Clocks) 2367 { 2368 unsigned short iClockIndex = 0; 2369 for (iClockIndex = 0; iClockIndex < Clocks; iClockIndex++) { 2370 sclock(); 2371 } 2372 } 2373 2374 /* 2375 * 2376 * ispVMBypass 2377 * 2378 * This procedure takes care of the HIR, HDR, TIR, TDR for the 2379 * purpose of putting the other devices into Bypass mode. The 2380 * current state is checked to find out if it is at DRPAUSE or 2381 * IRPAUSE. If it is at DRPAUSE, perform bypass register scan. 2382 * If it is at IRPAUSE, scan into instruction registers the bypass 2383 * instruction. 2384 * 2385 */ 2386 2387 void ispVMBypass(signed char ScanType, unsigned short Bits) 2388 { 2389 /* 09/11/07 NN added local variables initialization */ 2390 unsigned short iIndex = 0; 2391 unsigned short iSourceIndex = 0; 2392 unsigned char cBitState = 0; 2393 unsigned char cCurByte = 0; 2394 unsigned char *pcSource = NULL; 2395 2396 if (Bits <= 0) { 2397 return; 2398 } 2399 2400 switch (ScanType) { 2401 case HIR: 2402 pcSource = g_pucHIRData; 2403 break; 2404 case TIR: 2405 pcSource = g_pucTIRData; 2406 break; 2407 case HDR: 2408 pcSource = g_pucHDRData; 2409 break; 2410 case TDR: 2411 pcSource = g_pucTDRData; 2412 break; 2413 default: 2414 break; 2415 } 2416 2417 iSourceIndex = 0; 2418 cBitState = 0; 2419 for (iIndex = 0; iIndex < Bits - 1; iIndex++) { 2420 /* Scan instruction or bypass register */ 2421 if (iIndex % 8 == 0) { 2422 cCurByte = pcSource[iSourceIndex++]; 2423 } 2424 cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80) 2425 ? 0x01 : 0x00); 2426 writePort(g_ucPinTDI, cBitState); 2427 sclock(); 2428 } 2429 2430 if (iIndex % 8 == 0) { 2431 cCurByte = pcSource[iSourceIndex++]; 2432 } 2433 2434 cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80) 2435 ? 0x01 : 0x00); 2436 writePort(g_ucPinTDI, cBitState); 2437 } 2438 2439 /* 2440 * 2441 * ispVMStateMachine 2442 * 2443 * This procedure steps all devices in the daisy chain from a given 2444 * JTAG state to the next desirable state. If the next state is TLR, 2445 * the JTAG state machine is brute forced into TLR by driving TMS 2446 * high and pulse TCK 6 times. 2447 * 2448 */ 2449 2450 void ispVMStateMachine(signed char cNextJTAGState) 2451 { 2452 /* 09/11/07 NN added local variables initialization */ 2453 signed char cPathIndex = 0; 2454 signed char cStateIndex = 0; 2455 2456 if ((g_cCurrentJTAGState == cNextJTAGState) && 2457 (cNextJTAGState != RESET)) { 2458 return; 2459 } 2460 2461 for (cStateIndex = 0; cStateIndex < 25; cStateIndex++) { 2462 if ((g_cCurrentJTAGState == 2463 g_JTAGTransistions[cStateIndex].CurState) && 2464 (cNextJTAGState == 2465 g_JTAGTransistions[cStateIndex].NextState)) { 2466 break; 2467 } 2468 } 2469 2470 g_cCurrentJTAGState = cNextJTAGState; 2471 for (cPathIndex = 0; 2472 cPathIndex < g_JTAGTransistions[cStateIndex].Pulses; 2473 cPathIndex++) { 2474 if ((g_JTAGTransistions[cStateIndex].Pattern << cPathIndex) 2475 & 0x80) { 2476 writePort(g_ucPinTMS, (unsigned char) 0x01); 2477 } else { 2478 writePort(g_ucPinTMS, (unsigned char) 0x00); 2479 } 2480 sclock(); 2481 } 2482 2483 writePort(g_ucPinTDI, 0x00); 2484 writePort(g_ucPinTMS, 0x00); 2485 } 2486 2487 /* 2488 * 2489 * ispVMStart 2490 * 2491 * Enable the port to the device and set the state to RESET (TLR). 2492 * 2493 */ 2494 2495 void ispVMStart() 2496 { 2497 #ifdef DEBUG 2498 printf("// ISPVM EMBEDDED ADDED\n"); 2499 printf("STATE RESET;\n"); 2500 #endif 2501 g_usFlowControl = 0; 2502 g_usDataType = g_uiChecksumIndex = g_cCurrentJTAGState = 0; 2503 g_usHeadDR = g_usHeadIR = g_usTailDR = g_usTailIR = 0; 2504 g_usMaxSize = g_usShiftValue = g_usRepeatLoops = 0; 2505 g_usTDOSize = g_usMASKSize = g_usTDISize = 0; 2506 g_usDMASKSize = g_usLCOUNTSize = g_usHDRSize = 0; 2507 g_usTDRSize = g_usHIRSize = g_usTIRSize = g_usHeapSize = 0; 2508 g_pLVDSList = NULL; 2509 g_usLVDSPairCount = 0; 2510 previous_size = 0; 2511 2512 ispVMStateMachine(RESET); /*step devices to RESET state*/ 2513 } 2514 2515 /* 2516 * 2517 * ispVMEnd 2518 * 2519 * Set the state of devices to RESET to enable the devices and disable 2520 * the port. 2521 * 2522 */ 2523 2524 void ispVMEnd() 2525 { 2526 #ifdef DEBUG 2527 printf("// ISPVM EMBEDDED ADDED\n"); 2528 printf("STATE RESET;\n"); 2529 printf("RUNTEST 1.00E-001 SEC;\n"); 2530 #endif 2531 2532 ispVMStateMachine(RESET); /*step devices to RESET state */ 2533 ispVMDelay(1000); /*wake up devices*/ 2534 } 2535 2536 /* 2537 * 2538 * ispVMSend 2539 * 2540 * Send the TDI data stream to devices. The data stream can be 2541 * instructions or data. 2542 * 2543 */ 2544 2545 signed char ispVMSend(unsigned short a_usiDataSize) 2546 { 2547 /* 09/11/07 NN added local variables initialization */ 2548 unsigned short iIndex = 0; 2549 unsigned short iInDataIndex = 0; 2550 unsigned char cCurByte = 0; 2551 unsigned char cBitState = 0; 2552 2553 for (iIndex = 0; iIndex < a_usiDataSize - 1; iIndex++) { 2554 if (iIndex % 8 == 0) { 2555 cCurByte = g_pucInData[iInDataIndex++]; 2556 } 2557 cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) 2558 ? 0x01 : 0x00); 2559 writePort(g_ucPinTDI, cBitState); 2560 sclock(); 2561 } 2562 2563 if (iIndex % 8 == 0) { 2564 /* Take care of the last bit */ 2565 cCurByte = g_pucInData[iInDataIndex]; 2566 } 2567 2568 cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80) 2569 ? 0x01 : 0x00); 2570 2571 writePort(g_ucPinTDI, cBitState); 2572 if (g_usFlowControl & CASCADE) { 2573 /*1/15/04 Clock in last bit for the first n-1 cascaded frames */ 2574 sclock(); 2575 } 2576 2577 return 0; 2578 } 2579 2580 /* 2581 * 2582 * ispVMRead 2583 * 2584 * Read the data stream from devices and verify. 2585 * 2586 */ 2587 2588 signed char ispVMRead(unsigned short a_usiDataSize) 2589 { 2590 /* 09/11/07 NN added local variables initialization */ 2591 unsigned short usDataSizeIndex = 0; 2592 unsigned short usErrorCount = 0; 2593 unsigned short usLastBitIndex = 0; 2594 unsigned char cDataByte = 0; 2595 unsigned char cMaskByte = 0; 2596 unsigned char cInDataByte = 0; 2597 unsigned char cCurBit = 0; 2598 unsigned char cByteIndex = 0; 2599 unsigned short usBufferIndex = 0; 2600 unsigned char ucDisplayByte = 0x00; 2601 unsigned char ucDisplayFlag = 0x01; 2602 char StrChecksum[256] = {0}; 2603 unsigned char g_usCalculateChecksum = 0x00; 2604 2605 /* 09/11/07 NN Type cast mismatch variables */ 2606 usLastBitIndex = (unsigned short)(a_usiDataSize - 1); 2607 2608 #ifndef DEBUG 2609 /* 2610 * If mask is not all zeros, then set the display flag to 0x00, 2611 * otherwise it shall be set to 0x01 to indicate that data read 2612 * from the device shall be displayed. If DEBUG is defined, 2613 * always display data. 2614 */ 2615 2616 for (usDataSizeIndex = 0; usDataSizeIndex < (a_usiDataSize + 7) / 8; 2617 usDataSizeIndex++) { 2618 if (g_usDataType & MASK_DATA) { 2619 if (g_pucOutMaskData[usDataSizeIndex] != 0x00) { 2620 ucDisplayFlag = 0x00; 2621 break; 2622 } 2623 } else if (g_usDataType & CMASK_DATA) { 2624 g_usCalculateChecksum = 0x01; 2625 ucDisplayFlag = 0x00; 2626 break; 2627 } else { 2628 ucDisplayFlag = 0x00; 2629 break; 2630 } 2631 } 2632 #endif /* DEBUG */ 2633 2634 /* 2635 * 2636 * Begin shifting data in and out of the device. 2637 * 2638 **/ 2639 2640 for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; 2641 usDataSizeIndex++) { 2642 if (cByteIndex == 0) { 2643 2644 /* 2645 * Grab byte from TDO buffer. 2646 */ 2647 2648 if (g_usDataType & TDO_DATA) { 2649 cDataByte = g_pucOutData[usBufferIndex]; 2650 } 2651 2652 /* 2653 * Grab byte from MASK buffer. 2654 */ 2655 2656 if (g_usDataType & MASK_DATA) { 2657 cMaskByte = g_pucOutMaskData[usBufferIndex]; 2658 } else { 2659 cMaskByte = 0xFF; 2660 } 2661 2662 /* 2663 * Grab byte from CMASK buffer. 2664 */ 2665 2666 if (g_usDataType & CMASK_DATA) { 2667 cMaskByte = 0x00; 2668 g_usCalculateChecksum = 0x01; 2669 } 2670 2671 /* 2672 * Grab byte from TDI buffer. 2673 */ 2674 2675 if (g_usDataType & TDI_DATA) { 2676 cInDataByte = g_pucInData[usBufferIndex]; 2677 } 2678 2679 usBufferIndex++; 2680 } 2681 2682 cCurBit = readPort(); 2683 2684 if (ucDisplayFlag) { 2685 ucDisplayByte <<= 1; 2686 ucDisplayByte |= cCurBit; 2687 } 2688 2689 /* 2690 * Check if data read from port matches with expected TDO. 2691 */ 2692 2693 if (g_usDataType & TDO_DATA) { 2694 /* 08/28/08 NN Added Calculate checksum support. */ 2695 if (g_usCalculateChecksum) { 2696 if (cCurBit == 0x01) 2697 g_usChecksum += 2698 (1 << (g_uiChecksumIndex % 8)); 2699 g_uiChecksumIndex++; 2700 } else { 2701 if ((((cMaskByte << cByteIndex) & 0x80) 2702 ? 0x01 : 0x00)) { 2703 if (cCurBit != (unsigned char) 2704 (((cDataByte << cByteIndex) & 0x80) 2705 ? 0x01 : 0x00)) { 2706 usErrorCount++; 2707 } 2708 } 2709 } 2710 } 2711 2712 /* 2713 * Write TDI data to the port. 2714 */ 2715 2716 writePort(g_ucPinTDI, 2717 (unsigned char)(((cInDataByte << cByteIndex) & 0x80) 2718 ? 0x01 : 0x00)); 2719 2720 if (usDataSizeIndex < usLastBitIndex) { 2721 2722 /* 2723 * Clock data out from the data shift register. 2724 */ 2725 2726 sclock(); 2727 } else if (g_usFlowControl & CASCADE) { 2728 2729 /* 2730 * Clock in last bit for the first N - 1 cascaded frames 2731 */ 2732 2733 sclock(); 2734 } 2735 2736 /* 2737 * Increment the byte index. If it exceeds 7, then reset it back 2738 * to zero. 2739 */ 2740 2741 cByteIndex++; 2742 if (cByteIndex >= 8) { 2743 if (ucDisplayFlag) { 2744 2745 /* 2746 * Store displayed data in the TDO buffer. By reusing 2747 * the TDO buffer to store displayed data, there is no 2748 * need to allocate a buffer simply to hold display 2749 * data. This will not cause any false verification 2750 * errors because the true TDO byte has already 2751 * been consumed. 2752 */ 2753 2754 g_pucOutData[usBufferIndex - 1] = ucDisplayByte; 2755 ucDisplayByte = 0; 2756 } 2757 2758 cByteIndex = 0; 2759 } 2760 /* 09/12/07 Nguyen changed to display the 1 bit expected data */ 2761 else if (a_usiDataSize == 1) { 2762 if (ucDisplayFlag) { 2763 2764 /* 2765 * Store displayed data in the TDO buffer. 2766 * By reusing the TDO buffer to store displayed 2767 * data, there is no need to allocate 2768 * a buffer simply to hold display data. This 2769 * will not cause any false verification errors 2770 * because the true TDO byte has already 2771 * been consumed. 2772 */ 2773 2774 /* 2775 * Flip ucDisplayByte and store it in cDataByte. 2776 */ 2777 cDataByte = 0x00; 2778 for (usBufferIndex = 0; usBufferIndex < 8; 2779 usBufferIndex++) { 2780 cDataByte <<= 1; 2781 if (ucDisplayByte & 0x01) { 2782 cDataByte |= 0x01; 2783 } 2784 ucDisplayByte >>= 1; 2785 } 2786 g_pucOutData[0] = cDataByte; 2787 ucDisplayByte = 0; 2788 } 2789 2790 cByteIndex = 0; 2791 } 2792 } 2793 2794 if (ucDisplayFlag) { 2795 2796 #ifdef DEBUG 2797 debug("RECEIVED TDO ("); 2798 #else 2799 vme_out_string("Display Data: 0x"); 2800 #endif /* DEBUG */ 2801 2802 /* 09/11/07 NN Type cast mismatch variables */ 2803 for (usDataSizeIndex = (unsigned short) 2804 ((a_usiDataSize + 7) / 8); 2805 usDataSizeIndex > 0 ; usDataSizeIndex--) { 2806 cMaskByte = g_pucOutData[usDataSizeIndex - 1]; 2807 cDataByte = 0x00; 2808 2809 /* 2810 * Flip cMaskByte and store it in cDataByte. 2811 */ 2812 2813 for (usBufferIndex = 0; usBufferIndex < 8; 2814 usBufferIndex++) { 2815 cDataByte <<= 1; 2816 if (cMaskByte & 0x01) { 2817 cDataByte |= 0x01; 2818 } 2819 cMaskByte >>= 1; 2820 } 2821 #ifdef DEBUG 2822 printf("%.2X", cDataByte); 2823 if ((((a_usiDataSize + 7) / 8) - usDataSizeIndex) 2824 % 40 == 39) { 2825 printf("\n\t\t"); 2826 } 2827 #else 2828 vme_out_hex(cDataByte); 2829 #endif /* DEBUG */ 2830 } 2831 2832 #ifdef DEBUG 2833 printf(")\n\n"); 2834 #else 2835 vme_out_string("\n\n"); 2836 #endif /* DEBUG */ 2837 /* 09/02/08 Nguyen changed to display the data Checksum */ 2838 if (g_usChecksum != 0) { 2839 g_usChecksum &= 0xFFFF; 2840 sprintf(StrChecksum, "Data Checksum: %.4lX\n\n", 2841 g_usChecksum); 2842 vme_out_string(StrChecksum); 2843 g_usChecksum = 0; 2844 } 2845 } 2846 2847 if (usErrorCount > 0) { 2848 if (g_usFlowControl & VERIFYUES) { 2849 vme_out_string( 2850 "USERCODE verification failed. " 2851 "Continue programming......\n\n"); 2852 g_usFlowControl &= ~(VERIFYUES); 2853 return 0; 2854 } else { 2855 2856 #ifdef DEBUG 2857 printf("TOTAL ERRORS: %d\n", usErrorCount); 2858 #endif /* DEBUG */ 2859 2860 return VME_VERIFICATION_FAILURE; 2861 } 2862 } else { 2863 if (g_usFlowControl & VERIFYUES) { 2864 vme_out_string("USERCODE verification passed. " 2865 "Programming aborted.\n\n"); 2866 g_usFlowControl &= ~(VERIFYUES); 2867 return 1; 2868 } else { 2869 return 0; 2870 } 2871 } 2872 } 2873 2874 /* 2875 * 2876 * ispVMReadandSave 2877 * 2878 * Support dynamic I/O. 2879 * 2880 */ 2881 2882 signed char ispVMReadandSave(unsigned short int a_usiDataSize) 2883 { 2884 /* 09/11/07 NN added local variables initialization */ 2885 unsigned short int usDataSizeIndex = 0; 2886 unsigned short int usLastBitIndex = 0; 2887 unsigned short int usBufferIndex = 0; 2888 unsigned short int usOutBitIndex = 0; 2889 unsigned short int usLVDSIndex = 0; 2890 unsigned char cDataByte = 0; 2891 unsigned char cDMASKByte = 0; 2892 unsigned char cInDataByte = 0; 2893 unsigned char cCurBit = 0; 2894 unsigned char cByteIndex = 0; 2895 signed char cLVDSByteIndex = 0; 2896 2897 /* 09/11/07 NN Type cast mismatch variables */ 2898 usLastBitIndex = (unsigned short) (a_usiDataSize - 1); 2899 2900 /* 2901 * 2902 * Iterate through the data bits. 2903 * 2904 */ 2905 2906 for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; 2907 usDataSizeIndex++) { 2908 if (cByteIndex == 0) { 2909 2910 /* 2911 * Grab byte from DMASK buffer. 2912 */ 2913 2914 if (g_usDataType & DMASK_DATA) { 2915 cDMASKByte = g_pucOutDMaskData[usBufferIndex]; 2916 } else { 2917 cDMASKByte = 0x00; 2918 } 2919 2920 /* 2921 * Grab byte from TDI buffer. 2922 */ 2923 2924 if (g_usDataType & TDI_DATA) { 2925 cInDataByte = g_pucInData[usBufferIndex]; 2926 } 2927 2928 usBufferIndex++; 2929 } 2930 2931 cCurBit = readPort(); 2932 cDataByte = (unsigned char)(((cInDataByte << cByteIndex) & 0x80) 2933 ? 0x01 : 0x00); 2934 2935 /* 2936 * Initialize the byte to be zero. 2937 */ 2938 2939 if (usOutBitIndex % 8 == 0) { 2940 g_pucOutData[usOutBitIndex / 8] = 0x00; 2941 } 2942 2943 /* 2944 * Use TDI, DMASK, and device TDO to create new TDI (actually 2945 * stored in g_pucOutData). 2946 */ 2947 2948 if ((((cDMASKByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) { 2949 2950 if (g_pLVDSList) { 2951 for (usLVDSIndex = 0; 2952 usLVDSIndex < g_usLVDSPairCount; 2953 usLVDSIndex++) { 2954 if (g_pLVDSList[usLVDSIndex]. 2955 usNegativeIndex == 2956 usDataSizeIndex) { 2957 g_pLVDSList[usLVDSIndex]. 2958 ucUpdate = 0x01; 2959 break; 2960 } 2961 } 2962 } 2963 2964 /* 2965 * DMASK bit is 1, use TDI. 2966 */ 2967 2968 g_pucOutData[usOutBitIndex / 8] |= (unsigned char) 2969 (((cDataByte & 0x1) ? 0x01 : 0x00) << 2970 (7 - usOutBitIndex % 8)); 2971 } else { 2972 2973 /* 2974 * DMASK bit is 0, use device TDO. 2975 */ 2976 2977 g_pucOutData[usOutBitIndex / 8] |= (unsigned char) 2978 (((cCurBit & 0x1) ? 0x01 : 0x00) << 2979 (7 - usOutBitIndex % 8)); 2980 } 2981 2982 /* 2983 * Shift in TDI in order to get TDO out. 2984 */ 2985 2986 usOutBitIndex++; 2987 writePort(g_ucPinTDI, cDataByte); 2988 if (usDataSizeIndex < usLastBitIndex) { 2989 sclock(); 2990 } 2991 2992 /* 2993 * Increment the byte index. If it exceeds 7, then reset it back 2994 * to zero. 2995 */ 2996 2997 cByteIndex++; 2998 if (cByteIndex >= 8) { 2999 cByteIndex = 0; 3000 } 3001 } 3002 3003 /* 3004 * If g_pLVDSList exists and pairs need updating, then update 3005 * the negative-pair to receive the flipped positive-pair value. 3006 */ 3007 3008 if (g_pLVDSList) { 3009 for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; 3010 usLVDSIndex++) { 3011 if (g_pLVDSList[usLVDSIndex].ucUpdate) { 3012 3013 /* 3014 * Read the positive value and flip it. 3015 */ 3016 3017 cDataByte = (unsigned char) 3018 (((g_pucOutData[g_pLVDSList[usLVDSIndex]. 3019 usPositiveIndex / 8] 3020 << (g_pLVDSList[usLVDSIndex]. 3021 usPositiveIndex % 8)) & 0x80) ? 3022 0x01 : 0x00); 3023 /* 09/11/07 NN Type cast mismatch variables */ 3024 cDataByte = (unsigned char) (!cDataByte); 3025 3026 /* 3027 * Get the byte that needs modification. 3028 */ 3029 3030 cInDataByte = 3031 g_pucOutData[g_pLVDSList[usLVDSIndex]. 3032 usNegativeIndex / 8]; 3033 3034 if (cDataByte) { 3035 3036 /* 3037 * Copy over the current byte and 3038 * set the negative bit to 1. 3039 */ 3040 3041 cDataByte = 0x00; 3042 for (cLVDSByteIndex = 7; 3043 cLVDSByteIndex >= 0; 3044 cLVDSByteIndex--) { 3045 cDataByte <<= 1; 3046 if (7 - 3047 (g_pLVDSList[usLVDSIndex]. 3048 usNegativeIndex % 8) == 3049 cLVDSByteIndex) { 3050 3051 /* 3052 * Set negative bit to 1 3053 */ 3054 3055 cDataByte |= 0x01; 3056 } else if (cInDataByte & 0x80) { 3057 cDataByte |= 0x01; 3058 } 3059 3060 cInDataByte <<= 1; 3061 } 3062 3063 /* 3064 * Store the modified byte. 3065 */ 3066 3067 g_pucOutData[g_pLVDSList[usLVDSIndex]. 3068 usNegativeIndex / 8] = cDataByte; 3069 } else { 3070 3071 /* 3072 * Copy over the current byte and set 3073 * the negative bit to 0. 3074 */ 3075 3076 cDataByte = 0x00; 3077 for (cLVDSByteIndex = 7; 3078 cLVDSByteIndex >= 0; 3079 cLVDSByteIndex--) { 3080 cDataByte <<= 1; 3081 if (7 - 3082 (g_pLVDSList[usLVDSIndex]. 3083 usNegativeIndex % 8) == 3084 cLVDSByteIndex) { 3085 3086 /* 3087 * Set negative bit to 0 3088 */ 3089 3090 cDataByte |= 0x00; 3091 } else if (cInDataByte & 0x80) { 3092 cDataByte |= 0x01; 3093 } 3094 3095 cInDataByte <<= 1; 3096 } 3097 3098 /* 3099 * Store the modified byte. 3100 */ 3101 3102 g_pucOutData[g_pLVDSList[usLVDSIndex]. 3103 usNegativeIndex / 8] = cDataByte; 3104 } 3105 3106 break; 3107 } 3108 } 3109 } 3110 3111 return 0; 3112 } 3113 3114 signed char ispVMProcessLVDS(unsigned short a_usLVDSCount) 3115 { 3116 unsigned short usLVDSIndex = 0; 3117 3118 /* 3119 * Allocate memory to hold LVDS pairs. 3120 */ 3121 3122 ispVMMemManager(LVDS, a_usLVDSCount); 3123 g_usLVDSPairCount = a_usLVDSCount; 3124 3125 #ifdef DEBUG 3126 printf("LVDS %d (", a_usLVDSCount); 3127 #endif /* DEBUG */ 3128 3129 /* 3130 * Iterate through each given LVDS pair. 3131 */ 3132 3133 for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) { 3134 3135 /* 3136 * Assign the positive and negative indices of the LVDS pair. 3137 */ 3138 3139 /* 09/11/07 NN Type cast mismatch variables */ 3140 g_pLVDSList[usLVDSIndex].usPositiveIndex = 3141 (unsigned short) ispVMDataSize(); 3142 /* 09/11/07 NN Type cast mismatch variables */ 3143 g_pLVDSList[usLVDSIndex].usNegativeIndex = 3144 (unsigned short)ispVMDataSize(); 3145 3146 #ifdef DEBUG 3147 if (usLVDSIndex < g_usLVDSPairCount - 1) { 3148 printf("%d:%d, ", 3149 g_pLVDSList[usLVDSIndex].usPositiveIndex, 3150 g_pLVDSList[usLVDSIndex].usNegativeIndex); 3151 } else { 3152 printf("%d:%d", 3153 g_pLVDSList[usLVDSIndex].usPositiveIndex, 3154 g_pLVDSList[usLVDSIndex].usNegativeIndex); 3155 } 3156 #endif /* DEBUG */ 3157 3158 } 3159 3160 #ifdef DEBUG 3161 printf(");\n", a_usLVDSCount); 3162 #endif /* DEBUG */ 3163 3164 return 0; 3165 } 3166