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