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