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