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 unsigned char usByte = 0; 2106 2107 g_usIntelBufferSize = (unsigned short)ispVMDataSize(); 2108 2109 /* 2110 * Allocate memory for intel buffer. 2111 * 2112 */ 2113 2114 ispVMMemManager(LHEAP, g_usIntelBufferSize); 2115 2116 /* 2117 * Store the maximum size of the intelligent buffer. 2118 * Used to convert VME to HEX. 2119 */ 2120 2121 if (g_usIntelBufferSize > g_usLCOUNTSize) { 2122 g_usLCOUNTSize = g_usIntelBufferSize; 2123 } 2124 2125 /* 2126 * Copy intel data to the buffer. 2127 */ 2128 2129 for (usIntelBufferIndex = 0; usIntelBufferIndex < g_usIntelBufferSize; 2130 usIntelBufferIndex++) { 2131 g_pucIntelBuffer[usIntelBufferIndex] = GetByte(); 2132 } 2133 2134 /* 2135 * Set the data type register to get data from the intelligent 2136 * data buffer. 2137 */ 2138 2139 g_usDataType |= LHEAP_IN; 2140 2141 /* 2142 * 2143 * If the HEAP_IN flag is set, temporarily unset the flag so data will be 2144 * retrieved from the status buffer. 2145 * 2146 **/ 2147 2148 if (g_usDataType & HEAP_IN) { 2149 g_usDataType &= ~HEAP_IN; 2150 cRepeatHeap = 1; 2151 } 2152 2153 #ifdef DEBUG 2154 printf("LCOUNT %d;\n", a_usCountSize); 2155 #endif /* DEBUG */ 2156 2157 /* 2158 * Iterate through the intelligent programming command. 2159 */ 2160 2161 for (usCountIndex = 0; usCountIndex < a_usCountSize; usCountIndex++) { 2162 2163 /* 2164 * 2165 * Initialize the intel data index to 0 before each iteration. 2166 * 2167 **/ 2168 2169 g_usIntelDataIndex = 0; 2170 cOpcode = 0; 2171 ucState = 0; 2172 usDelay = 0; 2173 usToggle = 0; 2174 usByte = 0; 2175 usContinue = 1; 2176 2177 /* 2178 * 2179 * Begin looping through all the VME opcodes. 2180 * 2181 */ 2182 /* 2183 * 4/1/09 Nguyen replaced the recursive function call codes on 2184 * the ispVMLCOUNT function 2185 * 2186 */ 2187 while (usContinue) { 2188 cOpcode = GetByte(); 2189 switch (cOpcode) { 2190 case HIR: 2191 case TIR: 2192 case HDR: 2193 case TDR: 2194 /* 2195 * Set the header/trailer of the device in order 2196 * to bypass successfully. 2197 */ 2198 2199 ispVMAmble(cOpcode); 2200 break; 2201 case STATE: 2202 2203 /* 2204 * Step the JTAG state machine. 2205 */ 2206 2207 ucState = GetByte(); 2208 /* 2209 * Step the JTAG state machine to DRCAPTURE 2210 * to support Looping. 2211 */ 2212 2213 if ((g_usDataType & LHEAP_IN) && 2214 (ucState == DRPAUSE) && 2215 (g_cCurrentJTAGState == ucState)) { 2216 ispVMStateMachine(DRCAPTURE); 2217 } 2218 ispVMStateMachine(ucState); 2219 #ifdef DEBUG 2220 printf("LDELAY %s ", GetState(ucState)); 2221 #endif /* DEBUG */ 2222 break; 2223 case SIR: 2224 #ifdef DEBUG 2225 printf("SIR "); 2226 #endif /* DEBUG */ 2227 /* 2228 * Shift in data into the device. 2229 */ 2230 2231 cRetCode = ispVMShift(cOpcode); 2232 break; 2233 case SDR: 2234 2235 #ifdef DEBUG 2236 printf("LSDR "); 2237 #endif /* DEBUG */ 2238 /* 2239 * Shift in data into the device. 2240 */ 2241 2242 cRetCode = ispVMShift(cOpcode); 2243 break; 2244 case WAIT: 2245 2246 /* 2247 * 2248 * Observe delay. 2249 * 2250 */ 2251 2252 usDelay = (unsigned short)ispVMDataSize(); 2253 ispVMDelay(usDelay); 2254 2255 #ifdef DEBUG 2256 if (usDelay & 0x8000) { 2257 2258 /* 2259 * Since MSB is set, the delay time must 2260 * be decoded to millisecond. The 2261 * SVF2VME encodes the MSB to represent 2262 * millisecond. 2263 */ 2264 2265 usDelay &= ~0x8000; 2266 printf("%.2E SEC;\n", 2267 (float) usDelay / 1000); 2268 } else { 2269 /* 2270 * Since MSB is not set, the delay time 2271 * is given as microseconds. 2272 */ 2273 2274 printf("%.2E SEC;\n", 2275 (float) usDelay / 1000000); 2276 } 2277 #endif /* DEBUG */ 2278 break; 2279 case TCK: 2280 2281 /* 2282 * Issue clock toggles. 2283 */ 2284 2285 usToggle = (unsigned short)ispVMDataSize(); 2286 ispVMClocks(usToggle); 2287 2288 #ifdef DEBUG 2289 printf("RUNTEST %d TCK;\n", usToggle); 2290 #endif /* DEBUG */ 2291 break; 2292 case ENDLOOP: 2293 2294 /* 2295 * Exit point from processing loops. 2296 */ 2297 usContinue = 0; 2298 break; 2299 2300 case COMMENT: 2301 2302 /* 2303 * Display comment. 2304 */ 2305 2306 ispVMComment((unsigned short) ispVMDataSize()); 2307 break; 2308 case ispEN: 2309 ucState = GetByte(); 2310 if ((ucState == ON) || (ucState == 0x01)) 2311 writePort(g_ucPinENABLE, 0x01); 2312 else 2313 writePort(g_ucPinENABLE, 0x00); 2314 ispVMDelay(1); 2315 break; 2316 case TRST: 2317 if (GetByte() == 0x01) 2318 writePort(g_ucPinTRST, 0x01); 2319 else 2320 writePort(g_ucPinTRST, 0x00); 2321 ispVMDelay(1); 2322 break; 2323 default: 2324 2325 /* 2326 * Invalid opcode encountered. 2327 */ 2328 2329 debug("\nINVALID OPCODE: 0x%.2X\n", cOpcode); 2330 2331 return VME_INVALID_FILE; 2332 } 2333 } 2334 if (cRetCode >= 0) { 2335 /* 2336 * Break if intelligent programming is successful. 2337 */ 2338 2339 break; 2340 } 2341 2342 } 2343 /* 2344 * If HEAP_IN flag was temporarily disabled, 2345 * re-enable it before exiting 2346 */ 2347 2348 if (cRepeatHeap) { 2349 g_usDataType |= HEAP_IN; 2350 } 2351 2352 /* 2353 * Set the data type register to not get data from the 2354 * intelligent data buffer. 2355 */ 2356 2357 g_usDataType &= ~LHEAP_IN; 2358 return cRetCode; 2359 } 2360 /* 2361 * 2362 * ispVMClocks 2363 * 2364 * Applies the specified number of pulses to TCK. 2365 * 2366 */ 2367 2368 void ispVMClocks(unsigned short Clocks) 2369 { 2370 unsigned short iClockIndex = 0; 2371 for (iClockIndex = 0; iClockIndex < Clocks; iClockIndex++) { 2372 sclock(); 2373 } 2374 } 2375 2376 /* 2377 * 2378 * ispVMBypass 2379 * 2380 * This procedure takes care of the HIR, HDR, TIR, TDR for the 2381 * purpose of putting the other devices into Bypass mode. The 2382 * current state is checked to find out if it is at DRPAUSE or 2383 * IRPAUSE. If it is at DRPAUSE, perform bypass register scan. 2384 * If it is at IRPAUSE, scan into instruction registers the bypass 2385 * instruction. 2386 * 2387 */ 2388 2389 void ispVMBypass(signed char ScanType, unsigned short Bits) 2390 { 2391 /* 09/11/07 NN added local variables initialization */ 2392 unsigned short iIndex = 0; 2393 unsigned short iSourceIndex = 0; 2394 unsigned char cBitState = 0; 2395 unsigned char cCurByte = 0; 2396 unsigned char *pcSource = NULL; 2397 2398 if (Bits <= 0) { 2399 return; 2400 } 2401 2402 switch (ScanType) { 2403 case HIR: 2404 pcSource = g_pucHIRData; 2405 break; 2406 case TIR: 2407 pcSource = g_pucTIRData; 2408 break; 2409 case HDR: 2410 pcSource = g_pucHDRData; 2411 break; 2412 case TDR: 2413 pcSource = g_pucTDRData; 2414 break; 2415 default: 2416 break; 2417 } 2418 2419 iSourceIndex = 0; 2420 cBitState = 0; 2421 for (iIndex = 0; iIndex < Bits - 1; iIndex++) { 2422 /* Scan instruction or bypass register */ 2423 if (iIndex % 8 == 0) { 2424 cCurByte = pcSource[iSourceIndex++]; 2425 } 2426 cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80) 2427 ? 0x01 : 0x00); 2428 writePort(g_ucPinTDI, cBitState); 2429 sclock(); 2430 } 2431 2432 if (iIndex % 8 == 0) { 2433 cCurByte = pcSource[iSourceIndex++]; 2434 } 2435 2436 cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80) 2437 ? 0x01 : 0x00); 2438 writePort(g_ucPinTDI, cBitState); 2439 } 2440 2441 /* 2442 * 2443 * ispVMStateMachine 2444 * 2445 * This procedure steps all devices in the daisy chain from a given 2446 * JTAG state to the next desirable state. If the next state is TLR, 2447 * the JTAG state machine is brute forced into TLR by driving TMS 2448 * high and pulse TCK 6 times. 2449 * 2450 */ 2451 2452 void ispVMStateMachine(signed char cNextJTAGState) 2453 { 2454 /* 09/11/07 NN added local variables initialization */ 2455 signed char cPathIndex = 0; 2456 signed char cStateIndex = 0; 2457 2458 if ((g_cCurrentJTAGState == cNextJTAGState) && 2459 (cNextJTAGState != RESET)) { 2460 return; 2461 } 2462 2463 for (cStateIndex = 0; cStateIndex < 25; cStateIndex++) { 2464 if ((g_cCurrentJTAGState == 2465 g_JTAGTransistions[cStateIndex].CurState) && 2466 (cNextJTAGState == 2467 g_JTAGTransistions[cStateIndex].NextState)) { 2468 break; 2469 } 2470 } 2471 2472 g_cCurrentJTAGState = cNextJTAGState; 2473 for (cPathIndex = 0; 2474 cPathIndex < g_JTAGTransistions[cStateIndex].Pulses; 2475 cPathIndex++) { 2476 if ((g_JTAGTransistions[cStateIndex].Pattern << cPathIndex) 2477 & 0x80) { 2478 writePort(g_ucPinTMS, (unsigned char) 0x01); 2479 } else { 2480 writePort(g_ucPinTMS, (unsigned char) 0x00); 2481 } 2482 sclock(); 2483 } 2484 2485 writePort(g_ucPinTDI, 0x00); 2486 writePort(g_ucPinTMS, 0x00); 2487 } 2488 2489 /* 2490 * 2491 * ispVMStart 2492 * 2493 * Enable the port to the device and set the state to RESET (TLR). 2494 * 2495 */ 2496 2497 void ispVMStart() 2498 { 2499 #ifdef DEBUG 2500 printf("// ISPVM EMBEDDED ADDED\n"); 2501 printf("STATE RESET;\n"); 2502 #endif 2503 g_usFlowControl = 0; 2504 g_usDataType = g_uiChecksumIndex = g_cCurrentJTAGState = 0; 2505 g_usHeadDR = g_usHeadIR = g_usTailDR = g_usTailIR = 0; 2506 g_usMaxSize = g_usShiftValue = g_usRepeatLoops = 0; 2507 g_usTDOSize = g_usMASKSize = g_usTDISize = 0; 2508 g_usDMASKSize = g_usLCOUNTSize = g_usHDRSize = 0; 2509 g_usTDRSize = g_usHIRSize = g_usTIRSize = g_usHeapSize = 0; 2510 g_pLVDSList = NULL; 2511 g_usLVDSPairCount = 0; 2512 previous_size = 0; 2513 2514 ispVMStateMachine(RESET); /*step devices to RESET state*/ 2515 } 2516 2517 /* 2518 * 2519 * ispVMEnd 2520 * 2521 * Set the state of devices to RESET to enable the devices and disable 2522 * the port. 2523 * 2524 */ 2525 2526 void ispVMEnd() 2527 { 2528 #ifdef DEBUG 2529 printf("// ISPVM EMBEDDED ADDED\n"); 2530 printf("STATE RESET;\n"); 2531 printf("RUNTEST 1.00E-001 SEC;\n"); 2532 #endif 2533 2534 ispVMStateMachine(RESET); /*step devices to RESET state */ 2535 ispVMDelay(1000); /*wake up devices*/ 2536 } 2537 2538 /* 2539 * 2540 * ispVMSend 2541 * 2542 * Send the TDI data stream to devices. The data stream can be 2543 * instructions or data. 2544 * 2545 */ 2546 2547 signed char ispVMSend(unsigned short a_usiDataSize) 2548 { 2549 /* 09/11/07 NN added local variables initialization */ 2550 unsigned short iIndex = 0; 2551 unsigned short iInDataIndex = 0; 2552 unsigned char cCurByte = 0; 2553 unsigned char cBitState = 0; 2554 2555 for (iIndex = 0; iIndex < a_usiDataSize - 1; iIndex++) { 2556 if (iIndex % 8 == 0) { 2557 cCurByte = g_pucInData[iInDataIndex++]; 2558 } 2559 cBitState = (unsigned char)(((cCurByte << iIndex % 8) & 0x80) 2560 ? 0x01 : 0x00); 2561 writePort(g_ucPinTDI, cBitState); 2562 sclock(); 2563 } 2564 2565 if (iIndex % 8 == 0) { 2566 /* Take care of the last bit */ 2567 cCurByte = g_pucInData[iInDataIndex]; 2568 } 2569 2570 cBitState = (unsigned char) (((cCurByte << iIndex % 8) & 0x80) 2571 ? 0x01 : 0x00); 2572 2573 writePort(g_ucPinTDI, cBitState); 2574 if (g_usFlowControl & CASCADE) { 2575 /*1/15/04 Clock in last bit for the first n-1 cascaded frames */ 2576 sclock(); 2577 } 2578 2579 return 0; 2580 } 2581 2582 /* 2583 * 2584 * ispVMRead 2585 * 2586 * Read the data stream from devices and verify. 2587 * 2588 */ 2589 2590 signed char ispVMRead(unsigned short a_usiDataSize) 2591 { 2592 /* 09/11/07 NN added local variables initialization */ 2593 unsigned short usDataSizeIndex = 0; 2594 unsigned short usErrorCount = 0; 2595 unsigned short usLastBitIndex = 0; 2596 unsigned char cDataByte = 0; 2597 unsigned char cMaskByte = 0; 2598 unsigned char cInDataByte = 0; 2599 unsigned char cCurBit = 0; 2600 unsigned char cByteIndex = 0; 2601 unsigned short usBufferIndex = 0; 2602 unsigned char ucDisplayByte = 0x00; 2603 unsigned char ucDisplayFlag = 0x01; 2604 char StrChecksum[256] = {0}; 2605 unsigned char g_usCalculateChecksum = 0x00; 2606 2607 /* 09/11/07 NN Type cast mismatch variables */ 2608 usLastBitIndex = (unsigned short)(a_usiDataSize - 1); 2609 2610 #ifndef DEBUG 2611 /* 2612 * If mask is not all zeros, then set the display flag to 0x00, 2613 * otherwise it shall be set to 0x01 to indicate that data read 2614 * from the device shall be displayed. If DEBUG is defined, 2615 * always display data. 2616 */ 2617 2618 for (usDataSizeIndex = 0; usDataSizeIndex < (a_usiDataSize + 7) / 8; 2619 usDataSizeIndex++) { 2620 if (g_usDataType & MASK_DATA) { 2621 if (g_pucOutMaskData[usDataSizeIndex] != 0x00) { 2622 ucDisplayFlag = 0x00; 2623 break; 2624 } 2625 } else if (g_usDataType & CMASK_DATA) { 2626 g_usCalculateChecksum = 0x01; 2627 ucDisplayFlag = 0x00; 2628 break; 2629 } else { 2630 ucDisplayFlag = 0x00; 2631 break; 2632 } 2633 } 2634 #endif /* DEBUG */ 2635 2636 /* 2637 * 2638 * Begin shifting data in and out of the device. 2639 * 2640 **/ 2641 2642 for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; 2643 usDataSizeIndex++) { 2644 if (cByteIndex == 0) { 2645 2646 /* 2647 * Grab byte from TDO buffer. 2648 */ 2649 2650 if (g_usDataType & TDO_DATA) { 2651 cDataByte = g_pucOutData[usBufferIndex]; 2652 } 2653 2654 /* 2655 * Grab byte from MASK buffer. 2656 */ 2657 2658 if (g_usDataType & MASK_DATA) { 2659 cMaskByte = g_pucOutMaskData[usBufferIndex]; 2660 } else { 2661 cMaskByte = 0xFF; 2662 } 2663 2664 /* 2665 * Grab byte from CMASK buffer. 2666 */ 2667 2668 if (g_usDataType & CMASK_DATA) { 2669 cMaskByte = 0x00; 2670 g_usCalculateChecksum = 0x01; 2671 } 2672 2673 /* 2674 * Grab byte from TDI buffer. 2675 */ 2676 2677 if (g_usDataType & TDI_DATA) { 2678 cInDataByte = g_pucInData[usBufferIndex]; 2679 } 2680 2681 usBufferIndex++; 2682 } 2683 2684 cCurBit = readPort(); 2685 2686 if (ucDisplayFlag) { 2687 ucDisplayByte <<= 1; 2688 ucDisplayByte |= cCurBit; 2689 } 2690 2691 /* 2692 * Check if data read from port matches with expected TDO. 2693 */ 2694 2695 if (g_usDataType & TDO_DATA) { 2696 /* 08/28/08 NN Added Calculate checksum support. */ 2697 if (g_usCalculateChecksum) { 2698 if (cCurBit == 0x01) 2699 g_usChecksum += 2700 (1 << (g_uiChecksumIndex % 8)); 2701 g_uiChecksumIndex++; 2702 } else { 2703 if ((((cMaskByte << cByteIndex) & 0x80) 2704 ? 0x01 : 0x00)) { 2705 if (cCurBit != (unsigned char) 2706 (((cDataByte << cByteIndex) & 0x80) 2707 ? 0x01 : 0x00)) { 2708 usErrorCount++; 2709 } 2710 } 2711 } 2712 } 2713 2714 /* 2715 * Write TDI data to the port. 2716 */ 2717 2718 writePort(g_ucPinTDI, 2719 (unsigned char)(((cInDataByte << cByteIndex) & 0x80) 2720 ? 0x01 : 0x00)); 2721 2722 if (usDataSizeIndex < usLastBitIndex) { 2723 2724 /* 2725 * Clock data out from the data shift register. 2726 */ 2727 2728 sclock(); 2729 } else if (g_usFlowControl & CASCADE) { 2730 2731 /* 2732 * Clock in last bit for the first N - 1 cascaded frames 2733 */ 2734 2735 sclock(); 2736 } 2737 2738 /* 2739 * Increment the byte index. If it exceeds 7, then reset it back 2740 * to zero. 2741 */ 2742 2743 cByteIndex++; 2744 if (cByteIndex >= 8) { 2745 if (ucDisplayFlag) { 2746 2747 /* 2748 * Store displayed data in the TDO buffer. By reusing 2749 * the TDO buffer to store displayed data, there is no 2750 * need to allocate a buffer simply to hold display 2751 * data. This will not cause any false verification 2752 * errors because the true TDO byte has already 2753 * been consumed. 2754 */ 2755 2756 g_pucOutData[usBufferIndex - 1] = ucDisplayByte; 2757 ucDisplayByte = 0; 2758 } 2759 2760 cByteIndex = 0; 2761 } 2762 /* 09/12/07 Nguyen changed to display the 1 bit expected data */ 2763 else if (a_usiDataSize == 1) { 2764 if (ucDisplayFlag) { 2765 2766 /* 2767 * Store displayed data in the TDO buffer. 2768 * By reusing the TDO buffer to store displayed 2769 * data, there is no need to allocate 2770 * a buffer simply to hold display data. This 2771 * will not cause any false verification errors 2772 * because the true TDO byte has already 2773 * been consumed. 2774 */ 2775 2776 /* 2777 * Flip ucDisplayByte and store it in cDataByte. 2778 */ 2779 cDataByte = 0x00; 2780 for (usBufferIndex = 0; usBufferIndex < 8; 2781 usBufferIndex++) { 2782 cDataByte <<= 1; 2783 if (ucDisplayByte & 0x01) { 2784 cDataByte |= 0x01; 2785 } 2786 ucDisplayByte >>= 1; 2787 } 2788 g_pucOutData[0] = cDataByte; 2789 ucDisplayByte = 0; 2790 } 2791 2792 cByteIndex = 0; 2793 } 2794 } 2795 2796 if (ucDisplayFlag) { 2797 2798 #ifdef DEBUG 2799 debug("RECEIVED TDO ("); 2800 #else 2801 vme_out_string("Display Data: 0x"); 2802 #endif /* DEBUG */ 2803 2804 /* 09/11/07 NN Type cast mismatch variables */ 2805 for (usDataSizeIndex = (unsigned short) 2806 ((a_usiDataSize + 7) / 8); 2807 usDataSizeIndex > 0 ; usDataSizeIndex--) { 2808 cMaskByte = g_pucOutData[usDataSizeIndex - 1]; 2809 cDataByte = 0x00; 2810 2811 /* 2812 * Flip cMaskByte and store it in cDataByte. 2813 */ 2814 2815 for (usBufferIndex = 0; usBufferIndex < 8; 2816 usBufferIndex++) { 2817 cDataByte <<= 1; 2818 if (cMaskByte & 0x01) { 2819 cDataByte |= 0x01; 2820 } 2821 cMaskByte >>= 1; 2822 } 2823 #ifdef DEBUG 2824 printf("%.2X", cDataByte); 2825 if ((((a_usiDataSize + 7) / 8) - usDataSizeIndex) 2826 % 40 == 39) { 2827 printf("\n\t\t"); 2828 } 2829 #else 2830 vme_out_hex(cDataByte); 2831 #endif /* DEBUG */ 2832 } 2833 2834 #ifdef DEBUG 2835 printf(")\n\n"); 2836 #else 2837 vme_out_string("\n\n"); 2838 #endif /* DEBUG */ 2839 /* 09/02/08 Nguyen changed to display the data Checksum */ 2840 if (g_usChecksum != 0) { 2841 g_usChecksum &= 0xFFFF; 2842 sprintf(StrChecksum, "Data Checksum: %.4lX\n\n", 2843 g_usChecksum); 2844 vme_out_string(StrChecksum); 2845 g_usChecksum = 0; 2846 } 2847 } 2848 2849 if (usErrorCount > 0) { 2850 if (g_usFlowControl & VERIFYUES) { 2851 vme_out_string( 2852 "USERCODE verification failed. " 2853 "Continue programming......\n\n"); 2854 g_usFlowControl &= ~(VERIFYUES); 2855 return 0; 2856 } else { 2857 2858 #ifdef DEBUG 2859 printf("TOTAL ERRORS: %d\n", usErrorCount); 2860 #endif /* DEBUG */ 2861 2862 return VME_VERIFICATION_FAILURE; 2863 } 2864 } else { 2865 if (g_usFlowControl & VERIFYUES) { 2866 vme_out_string("USERCODE verification passed. " 2867 "Programming aborted.\n\n"); 2868 g_usFlowControl &= ~(VERIFYUES); 2869 return 1; 2870 } else { 2871 return 0; 2872 } 2873 } 2874 } 2875 2876 /* 2877 * 2878 * ispVMReadandSave 2879 * 2880 * Support dynamic I/O. 2881 * 2882 */ 2883 2884 signed char ispVMReadandSave(unsigned short int a_usiDataSize) 2885 { 2886 /* 09/11/07 NN added local variables initialization */ 2887 unsigned short int usDataSizeIndex = 0; 2888 unsigned short int usLastBitIndex = 0; 2889 unsigned short int usBufferIndex = 0; 2890 unsigned short int usOutBitIndex = 0; 2891 unsigned short int usLVDSIndex = 0; 2892 unsigned char cDataByte = 0; 2893 unsigned char cDMASKByte = 0; 2894 unsigned char cInDataByte = 0; 2895 unsigned char cCurBit = 0; 2896 unsigned char cByteIndex = 0; 2897 signed char cLVDSByteIndex = 0; 2898 2899 /* 09/11/07 NN Type cast mismatch variables */ 2900 usLastBitIndex = (unsigned short) (a_usiDataSize - 1); 2901 2902 /* 2903 * 2904 * Iterate through the data bits. 2905 * 2906 */ 2907 2908 for (usDataSizeIndex = 0; usDataSizeIndex < a_usiDataSize; 2909 usDataSizeIndex++) { 2910 if (cByteIndex == 0) { 2911 2912 /* 2913 * Grab byte from DMASK buffer. 2914 */ 2915 2916 if (g_usDataType & DMASK_DATA) { 2917 cDMASKByte = g_pucOutDMaskData[usBufferIndex]; 2918 } else { 2919 cDMASKByte = 0x00; 2920 } 2921 2922 /* 2923 * Grab byte from TDI buffer. 2924 */ 2925 2926 if (g_usDataType & TDI_DATA) { 2927 cInDataByte = g_pucInData[usBufferIndex]; 2928 } 2929 2930 usBufferIndex++; 2931 } 2932 2933 cCurBit = readPort(); 2934 cDataByte = (unsigned char)(((cInDataByte << cByteIndex) & 0x80) 2935 ? 0x01 : 0x00); 2936 2937 /* 2938 * Initialize the byte to be zero. 2939 */ 2940 2941 if (usOutBitIndex % 8 == 0) { 2942 g_pucOutData[usOutBitIndex / 8] = 0x00; 2943 } 2944 2945 /* 2946 * Use TDI, DMASK, and device TDO to create new TDI (actually 2947 * stored in g_pucOutData). 2948 */ 2949 2950 if ((((cDMASKByte << cByteIndex) & 0x80) ? 0x01 : 0x00)) { 2951 2952 if (g_pLVDSList) { 2953 for (usLVDSIndex = 0; 2954 usLVDSIndex < g_usLVDSPairCount; 2955 usLVDSIndex++) { 2956 if (g_pLVDSList[usLVDSIndex]. 2957 usNegativeIndex == 2958 usDataSizeIndex) { 2959 g_pLVDSList[usLVDSIndex]. 2960 ucUpdate = 0x01; 2961 break; 2962 } 2963 } 2964 } 2965 2966 /* 2967 * DMASK bit is 1, use TDI. 2968 */ 2969 2970 g_pucOutData[usOutBitIndex / 8] |= (unsigned char) 2971 (((cDataByte & 0x1) ? 0x01 : 0x00) << 2972 (7 - usOutBitIndex % 8)); 2973 } else { 2974 2975 /* 2976 * DMASK bit is 0, use device TDO. 2977 */ 2978 2979 g_pucOutData[usOutBitIndex / 8] |= (unsigned char) 2980 (((cCurBit & 0x1) ? 0x01 : 0x00) << 2981 (7 - usOutBitIndex % 8)); 2982 } 2983 2984 /* 2985 * Shift in TDI in order to get TDO out. 2986 */ 2987 2988 usOutBitIndex++; 2989 writePort(g_ucPinTDI, cDataByte); 2990 if (usDataSizeIndex < usLastBitIndex) { 2991 sclock(); 2992 } 2993 2994 /* 2995 * Increment the byte index. If it exceeds 7, then reset it back 2996 * to zero. 2997 */ 2998 2999 cByteIndex++; 3000 if (cByteIndex >= 8) { 3001 cByteIndex = 0; 3002 } 3003 } 3004 3005 /* 3006 * If g_pLVDSList exists and pairs need updating, then update 3007 * the negative-pair to receive the flipped positive-pair value. 3008 */ 3009 3010 if (g_pLVDSList) { 3011 for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; 3012 usLVDSIndex++) { 3013 if (g_pLVDSList[usLVDSIndex].ucUpdate) { 3014 3015 /* 3016 * Read the positive value and flip it. 3017 */ 3018 3019 cDataByte = (unsigned char) 3020 (((g_pucOutData[g_pLVDSList[usLVDSIndex]. 3021 usPositiveIndex / 8] 3022 << (g_pLVDSList[usLVDSIndex]. 3023 usPositiveIndex % 8)) & 0x80) ? 3024 0x01 : 0x00); 3025 /* 09/11/07 NN Type cast mismatch variables */ 3026 cDataByte = (unsigned char) (!cDataByte); 3027 3028 /* 3029 * Get the byte that needs modification. 3030 */ 3031 3032 cInDataByte = 3033 g_pucOutData[g_pLVDSList[usLVDSIndex]. 3034 usNegativeIndex / 8]; 3035 3036 if (cDataByte) { 3037 3038 /* 3039 * Copy over the current byte and 3040 * set the negative bit to 1. 3041 */ 3042 3043 cDataByte = 0x00; 3044 for (cLVDSByteIndex = 7; 3045 cLVDSByteIndex >= 0; 3046 cLVDSByteIndex--) { 3047 cDataByte <<= 1; 3048 if (7 - 3049 (g_pLVDSList[usLVDSIndex]. 3050 usNegativeIndex % 8) == 3051 cLVDSByteIndex) { 3052 3053 /* 3054 * Set negative bit to 1 3055 */ 3056 3057 cDataByte |= 0x01; 3058 } else if (cInDataByte & 0x80) { 3059 cDataByte |= 0x01; 3060 } 3061 3062 cInDataByte <<= 1; 3063 } 3064 3065 /* 3066 * Store the modified byte. 3067 */ 3068 3069 g_pucOutData[g_pLVDSList[usLVDSIndex]. 3070 usNegativeIndex / 8] = cDataByte; 3071 } else { 3072 3073 /* 3074 * Copy over the current byte and set 3075 * the negative bit to 0. 3076 */ 3077 3078 cDataByte = 0x00; 3079 for (cLVDSByteIndex = 7; 3080 cLVDSByteIndex >= 0; 3081 cLVDSByteIndex--) { 3082 cDataByte <<= 1; 3083 if (7 - 3084 (g_pLVDSList[usLVDSIndex]. 3085 usNegativeIndex % 8) == 3086 cLVDSByteIndex) { 3087 3088 /* 3089 * Set negative bit to 0 3090 */ 3091 3092 cDataByte |= 0x00; 3093 } else if (cInDataByte & 0x80) { 3094 cDataByte |= 0x01; 3095 } 3096 3097 cInDataByte <<= 1; 3098 } 3099 3100 /* 3101 * Store the modified byte. 3102 */ 3103 3104 g_pucOutData[g_pLVDSList[usLVDSIndex]. 3105 usNegativeIndex / 8] = cDataByte; 3106 } 3107 3108 break; 3109 } 3110 } 3111 } 3112 3113 return 0; 3114 } 3115 3116 signed char ispVMProcessLVDS(unsigned short a_usLVDSCount) 3117 { 3118 unsigned short usLVDSIndex = 0; 3119 3120 /* 3121 * Allocate memory to hold LVDS pairs. 3122 */ 3123 3124 ispVMMemManager(LVDS, a_usLVDSCount); 3125 g_usLVDSPairCount = a_usLVDSCount; 3126 3127 #ifdef DEBUG 3128 printf("LVDS %d (", a_usLVDSCount); 3129 #endif /* DEBUG */ 3130 3131 /* 3132 * Iterate through each given LVDS pair. 3133 */ 3134 3135 for (usLVDSIndex = 0; usLVDSIndex < g_usLVDSPairCount; usLVDSIndex++) { 3136 3137 /* 3138 * Assign the positive and negative indices of the LVDS pair. 3139 */ 3140 3141 /* 09/11/07 NN Type cast mismatch variables */ 3142 g_pLVDSList[usLVDSIndex].usPositiveIndex = 3143 (unsigned short) ispVMDataSize(); 3144 /* 09/11/07 NN Type cast mismatch variables */ 3145 g_pLVDSList[usLVDSIndex].usNegativeIndex = 3146 (unsigned short)ispVMDataSize(); 3147 3148 #ifdef DEBUG 3149 if (usLVDSIndex < g_usLVDSPairCount - 1) { 3150 printf("%d:%d, ", 3151 g_pLVDSList[usLVDSIndex].usPositiveIndex, 3152 g_pLVDSList[usLVDSIndex].usNegativeIndex); 3153 } else { 3154 printf("%d:%d", 3155 g_pLVDSList[usLVDSIndex].usPositiveIndex, 3156 g_pLVDSList[usLVDSIndex].usNegativeIndex); 3157 } 3158 #endif /* DEBUG */ 3159 3160 } 3161 3162 #ifdef DEBUG 3163 printf(");\n", a_usLVDSCount); 3164 #endif /* DEBUG */ 3165 3166 return 0; 3167 } 3168