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