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