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