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