957de1f8737a613f49789ec927d41cbf48a104da
[fx2fw-sdcc] / hw_xpcu_x.c
1 /*-----------------------------------------------------------------------------\r
2 \r
3  * Hardware-dependent code for usb_jtag\r
4 \r
5  *-----------------------------------------------------------------------------\r
6 \r
7  * Copyright (C) 2007 Kolja Waschk, ixo.de\r
8 \r
9  *-----------------------------------------------------------------------------\r
10 \r
11  * This code is part of usbjtag. usbjtag is free software; you can redistribute\r
12 \r
13  * it and/or modify it under the terms of the GNU General Public License as\r
14 \r
15  * published by the Free Software Foundation; either version 2 of the License,\r
16 \r
17  * or (at your option) any later version. usbjtag is distributed in the hope\r
18 \r
19  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied\r
20 \r
21  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
22 \r
23  * GNU General Public License for more details.  You should have received a\r
24 \r
25  * copy of the GNU General Public License along with this program in the file\r
26 \r
27  * COPYING; if not, write to the Free Software Foundation, Inc., 51 Franklin\r
28 \r
29  * St, Fifth Floor, Boston, MA  02110-1301  USA\r
30 \r
31  *-----------------------------------------------------------------------------\r
32 \r
33  */\r
34 \r
35 \r
36 \r
37 #include "delay.h"\r
38 \r
39 #include "syncdelay.h"\r
40 \r
41 #include "hardware.h"\r
42 \r
43 \r
44 \r
45 #include "isr.h"\r
46 \r
47 #include "timer.h"\r
48 \r
49 #include "delay.h"\r
50 \r
51 #include "fx2regs.h"\r
52 \r
53 #include "fx2utils.h"\r
54 \r
55 #include "usb_common.h"\r
56 \r
57 #include "usb_descriptors.h"\r
58 \r
59 #include "usb_requests.h"\r
60 \r
61 #include "syncdelay.h"\r
62 \r
63 #include "eeprom.h"\r
64 \r
65 \r
66 \r
67 #define HAVE_OE_LED 1\r
68 \r
69 sbit at 0x80+1        OELED; // red LED on S3E Starter Kit (0x80+0 is green one)\r
70 \r
71 #define SetOELED(x)   do{OELED=(x);}while(0)\r
72 \r
73 \r
74 \r
75 void ProgIO_Poll(void)    {}\r
76 \r
77 void ProgIO_Enable(void)  {}\r
78 \r
79 void ProgiO_Disable(void) {}\r
80 \r
81 void ProgiO_Deinit(void)  {}\r
82 \r
83 \r
84 \r
85 static unsigned char curios;\r
86 \r
87 \r
88 \r
89 const unsigned char wavedata[64] =\r
90 \r
91 {\r
92 \r
93   /* Single Write:\r
94 \r
95      s0: BITS=D0     NEXT/SGLCRC DATA WAIT 4\r
96 \r
97      s1: BITS=       DATA WAIT 4\r
98 \r
99      s2: BITS=D1|D0  DATA WAIT 4\r
100 \r
101      s3: BITS=D1     DATA WAIT 3\r
102 \r
103      s4: BITS=D1     DATA DP IF(RDY0) THEN 5 ELSE 2\r
104 \r
105      s5: BITS=D1|D0  DATA WAIT 4\r
106 \r
107      s6: BITS=D1     DATA WAIT 3\r
108 \r
109      s7: BITS=D1     DATA FIN */\r
110 \r
111 \r
112 \r
113   4, 4, 4, 3, 0x2A, 4, 3, 7,\r
114 \r
115   6, 2, 2, 2, 3,    2, 2, 2,\r
116 \r
117   1, 0, 3, 2, 2,    3, 2, 2,\r
118 \r
119   0, 0, 0, 0, 0,    0, 0, 0x3F,\r
120 \r
121 \r
122 \r
123   /* Single Read:\r
124 \r
125      s0: BITS=D0     WAIT 4\r
126 \r
127      s1: BITS=       WAIT 4\r
128 \r
129      s2: BITS=D1|D0  WAIT 4\r
130 \r
131      s3: BITS=D1     WAIT 4\r
132 \r
133      s4: BITS=D1|D0  WAIT 3\r
134 \r
135      s5: BITS=D1|D0  DP IF(RDY0) THEN 6 ELSE 3\r
136 \r
137      s6: BITS=D1     DATA WAIT 4\r
138 \r
139      s7: BITS=D1     FIN */\r
140 \r
141 \r
142 \r
143   4, 4, 4, 4, 3, 0x33, 4, 7,\r
144 \r
145   0, 0, 0, 0, 0, 1,    2, 0,\r
146 \r
147   1, 0, 3, 2, 3, 3,    2, 2,\r
148 \r
149   0, 0, 0, 0, 0, 0,    0, 0x3F\r
150 \r
151 };\r
152 \r
153 \r
154 \r
155 void ProgIO_Init(void)\r
156 \r
157 {\r
158 \r
159   unsigned char i;\r
160 \r
161 \r
162 \r
163   /* The following code depends on your actual circuit design.\r
164 \r
165      Make required changes _before_ you try the code! */\r
166 \r
167 \r
168 \r
169   // set the CPU clock to 48MHz, enable clock output to FPGA\r
170 \r
171   CPUCS = bmCLKOE | bmCLKSPD1;\r
172 \r
173 \r
174 \r
175   // Use internal 48 MHz, enable output, GPIF Master mode\r
176 \r
177   IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmIFGPIF;\r
178 \r
179 \r
180 \r
181   PORTACFG = 0x00; OEA = 0xFB; IOA = 0x20;\r
182 \r
183   PORTCCFG = 0x00; OEC = 0xFF; IOC = 0x10;\r
184 \r
185   PORTECFG = 0x00; OEE = 0xFC; IOE = 0xC0;\r
186 \r
187  \r
188 \r
189   GPIFABORT    = 0xFF;\r
190 \r
191 \r
192 \r
193   GPIFREADYCFG = 0xA0;\r
194 \r
195   GPIFCTLCFG   = 0x00;\r
196 \r
197   GPIFIDLECS   = 0x00;\r
198 \r
199   GPIFIDLECTL  = 0x00;\r
200 \r
201   GPIFWFSELECT = 0x01;\r
202 \r
203 \r
204 \r
205   // Copy waveform data\r
206 \r
207   AUTOPTRSETUP = 0x07;\r
208 \r
209   APTR1H = MSB( &wavedata );\r
210 \r
211   APTR1L = LSB( &wavedata );\r
212 \r
213   AUTOPTRH2 = 0xE4;\r
214 \r
215   AUTOPTRL2 = 0x00;\r
216 \r
217   for ( i = 0; i < 64; i++ ) EXTAUTODAT2 = EXTAUTODAT1;\r
218 \r
219 \r
220 \r
221   SYNCDELAY;\r
222 \r
223   GPIFADRH      = 0x00;\r
224 \r
225   SYNCDELAY;\r
226 \r
227   GPIFADRL      = 0x00;\r
228 \r
229 \r
230 \r
231   FLOWSTATE     = 0x00;\r
232 \r
233   FLOWLOGIC     = 0x00;\r
234 \r
235   FLOWEQ0CTL    = 0x00;\r
236 \r
237   FLOWEQ1CTL    = 0x00;\r
238 \r
239   FLOWHOLDOFF   = 0x00;\r
240 \r
241   FLOWSTB       = 0x00;\r
242 \r
243   FLOWSTBEDGE   = 0x00;\r
244 \r
245   FLOWSTBHPERIOD = 0x00;\r
246 \r
247 \r
248 \r
249   curios = 0;\r
250 \r
251 }\r
252 \r
253 \r
254 \r
255 unsigned char GetTDO(unsigned char r)\r
256 \r
257 {\r
258 \r
259   unsigned char x;\r
260 \r
261 \r
262 \r
263   IOC = 0x41;\r
264 \r
265   while(!(GPIFTRIG & 0x80)); x = XGPIFSGLDATLX;\r
266 \r
267   while(!(GPIFTRIG & 0x80)); x = XGPIFSGLDATLNOX;\r
268 \r
269 \r
270 \r
271   if(IOA & 0x20) IOA |= 0x40; else IOA &= ~0x40;\r
272 \r
273 \r
274 \r
275   return (x&1) ? r : 0;\r
276 \r
277 }\r
278 \r
279 \r
280 \r
281 #define SetPins(x) while(!(GPIFTRIG & 0x80)); XGPIFSGLDATLX = (x)\r
282 \r
283 \r
284 \r
285 void ProgIO_Set_State(unsigned char d)\r
286 \r
287 {\r
288 \r
289   /* Set state of output pins:\r
290 \r
291    *\r
292 \r
293    * d.0 => TCK (PE.6)\r
294 \r
295    * d.1 => TMS (PE.5)\r
296 \r
297    * d.4 => TDI (PE.4)\r
298 \r
299    * d.6 => LED / Output Enable\r
300 \r
301    */\r
302 \r
303  \r
304 \r
305   curios  = (d & bmBIT0) ? 0x40 : 0; // TCK\r
306 \r
307   curios |= (d & bmBIT1) ? 0x20 : 0; // TMS\r
308 \r
309   curios |= (d & bmBIT4) ? 0x10 : 0; // TDI\r
310 \r
311 \r
312 \r
313   IOC = 0x81;\r
314 \r
315   SetPins(curios);\r
316 \r
317 \r
318 \r
319   if(d & bmBIT6) IOA=(IOA&~3)|1; else IOA=(IOA&~3)|2;\r
320 \r
321 }\r
322 \r
323 \r
324 \r
325 unsigned char ProgIO_Set_Get_State(unsigned char d)\r
326 \r
327 {\r
328 \r
329   ProgIO_Set_State(d);\r
330 \r
331 \r
332 \r
333   /* Read state of input pins:\r
334 \r
335    *\r
336 \r
337    * TDO => d.0\r
338 \r
339    * DATAOUT => d.1 (only #ifdef HAVE_AS_MODE)\r
340 \r
341    */\r
342 \r
343 \r
344 \r
345   return 2|GetTDO(0x01);\r
346 \r
347 }\r
348 \r
349 \r
350 \r
351 void ProgIO_ShiftOut(unsigned char c)\r
352 \r
353 {\r
354 \r
355   unsigned char r,i;\r
356 \r
357   unsigned char locios = curios & ~0x50;\r
358 \r
359 \r
360 \r
361   IOC = 0x81;\r
362 \r
363 \r
364 \r
365   for(i=0,r=1;i<8;i++)\r
366 \r
367   {\r
368 \r
369     unsigned char t = locios;\r
370 \r
371     if(c & r) t |= 0x10;\r
372 \r
373     SetPins(t);\r
374 \r
375     SetPins(t|0x40);\r
376 \r
377     r <<= 1;\r
378 \r
379     SetPins(t);\r
380 \r
381   };\r
382 \r
383 \r
384 \r
385   curios = locios;\r
386 \r
387 }\r
388 \r
389 \r
390 \r
391 \r
392 \r
393 unsigned char ProgIO_ShiftInOut(unsigned char c)\r
394 \r
395 {\r
396 \r
397   unsigned char r,i,n;\r
398 \r
399   unsigned char locios = curios & ~0x50;\r
400 \r
401 \r
402 \r
403   for(i=0,r=1,n=0;i<8;i++)\r
404 \r
405   {\r
406 \r
407     unsigned char t = locios;\r
408 \r
409 \r
410 \r
411     n |= GetTDO(r);\r
412 \r
413 \r
414 \r
415     IOC = 0x81;\r
416 \r
417     if(c & r) t |= 0x10;\r
418 \r
419     SetPins(t);\r
420 \r
421     SetPins(t|0x40);\r
422 \r
423     r <<= 1;\r
424 \r
425     SetPins(t);\r
426 \r
427   };\r
428 \r
429 \r
430 \r
431   curios = locios;\r
432 \r
433   return n;\r
434 \r
435 }\r
436 \r
437 \r
438 \r
439 \r
440 \r