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