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