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