version 4.1.0 from http://fpga4u.epfl.ch/wiki/FX2
[fx2fw-sdcc] / hw_basic.c
1 /*-----------------------------------------------------------------------------\r
2  * Hardware-dependent code for usb_jtag\r
3  *-----------------------------------------------------------------------------\r
4  * Copyright (C) 2007 Kolja Waschk, ixo.de\r
5  *-----------------------------------------------------------------------------\r
6  * This code is part of usbjtag. usbjtag is free software; you can redistribute\r
7  * it and/or modify it under the terms of the GNU General Public License as\r
8  * published by the Free Software Foundation; either version 2 of the License,\r
9  * or (at your option) any later version. usbjtag is distributed in the hope\r
10  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied\r
11  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.  You should have received a\r
13  * copy of the GNU General Public License along with this program in the file\r
14  * COPYING; if not, write to the Free Software Foundation, Inc., 51 Franklin\r
15  * St, Fifth Floor, Boston, MA  02110-1301  USA\r
16  *-----------------------------------------------------------------------------\r
17  */\r
18 \r
19 #include <fx2regs.h>\r
20 #include "hardware.h"\r
21 #include "delay.h"\r
22 \r
23 //-----------------------------------------------------------------------------\r
24 \r
25 #define HAVE_PS_MODE 1\r
26 #define HAVE_AS_MODE 1\r
27 #define HAVE_OE_LED  1\r
28 \r
29 //-----------------------------------------------------------------------------\r
30 \r
31 /* JTAG TCK, AS/PS DCLK */\r
32 \r
33 sbit at 0xA2          TCK; /* Port C.0 */\r
34 #define bmTCKOE       bmBIT2\r
35 #define SetTCK(x)     do{TCK=(x);}while(0)\r
36 \r
37 /* JTAG TDI, AS ASDI, PS DATA0 */\r
38 \r
39 sbit at 0xA0          TDI; /* Port C.2 */\r
40 #define bmTDIOE       bmBIT0\r
41 #define SetTDI(x)     do{TDI=(x);}while(0)\r
42 \r
43 /* JTAG TMS, AS/PS nCONFIG */\r
44 \r
45 sbit at 0xA3          TMS; /* Port C.3 */\r
46 #define bmTMSOE       bmBIT3\r
47 #define SetTMS(x)     do{TMS=(x);}while(0)\r
48 \r
49 /* JTAG TDO, AS/PS CONF_DONE */\r
50 \r
51 sbit at 0xA1          TDO; /* Port C.1 */\r
52 #define bmTDOOE       bmBIT1\r
53 #define GetTDO(x)     TDO\r
54 \r
55 /* JTAG ENABLE */\r
56 sbit JTAG_EN = 0xA0+7;\r
57 #define bmJTAG_EN bmBIT7\r
58 \r
59 //-----------------------------------------------------------------------------\r
60 \r
61 #if defined(HAVE_PS_MODE) || defined(HAVE_AS_MODE)\r
62 \r
63   /* AS DATAOUT, PS nSTATUS */\r
64 \r
65   sbit at 0xA6        ASDO; /* Port C.6 */\r
66   #define bmASDOOE    bmBIT6\r
67   #define GetASDO(x)  ASDO\r
68 \r
69 #else\r
70 \r
71   #define bmASDOOE    0\r
72   #define GetASDO(x)  0\r
73 \r
74 #endif\r
75 \r
76 //-----------------------------------------------------------------------------\r
77 \r
78 #if defined(HAVE_AS_MODE)\r
79 \r
80   /* AS Mode nCS */\r
81 \r
82   sbit at 0xA4        NCS; /* Port C.4 */\r
83   #define bmNCSOE     bmBIT4\r
84   #define SetNCS(x)   do{NCS=(x);}while(0)\r
85   #define GetNCS(x)   NCS\r
86 \r
87   /* AS Mode nCE */\r
88 \r
89   sbit at 0xA5        NCE; /* Port C.5 */\r
90   #define bmNCEOE     bmBIT5\r
91   #define SetNCE(x)   do{NCE=(x);}while(0)\r
92 \r
93   unsigned char ProgIO_ShiftInOut_AS(unsigned char x);\r
94 \r
95 #else\r
96 \r
97   #define bmNCSOE     0\r
98   #define SetNCS(x)   while(0){}\r
99   #define GetNCS(x)   1\r
100   #define bmNCEOE     0\r
101   #define SetNCE(x)   while(0){}\r
102 \r
103   #define ProgIO_ShiftInOut_AS(x) ProgIO_ShiftInOut(x)\r
104 \r
105 #endif\r
106 \r
107 //-----------------------------------------------------------------------------\r
108 \r
109 #ifdef HAVE_OE_LED\r
110 \r
111   sbit at 0xA7        OELED; /* Port C.7 */\r
112   #define bmOELEDOE   bmBIT7\r
113   #define SetOELED(x) do{OELED=(x);}while(0)\r
114 \r
115 #else\r
116 \r
117   #define bmOELEDOE   0\r
118   #define SetOELED(x) while(0){}\r
119 \r
120 #endif\r
121 \r
122 //-----------------------------------------------------------------------------\r
123 \r
124 #define bmPROGOUTOE (bmTCKOE|bmTDIOE|bmTMSOE|bmNCEOE|bmNCSOE|bmOELEDOE)\r
125 #define bmPROGINOE  (bmTDOOE|bmASDOOE)\r
126 \r
127 //-----------------------------------------------------------------------------\r
128 \r
129 void ProgIO_Poll(void)    {}\r
130 // These aren't called anywhere in usbjtag.c, but I plan to do so...\r
131 void ProgIO_Enable(void)  {}\r
132 void ProgIO_Disable(void) {}\r
133 void ProgIO_Deinit(void)  {}\r
134 \r
135 \r
136 void ProgIO_Init(void)\r
137 {\r
138   /* The following code depends on your actual circuit design.\r
139      Make required changes _before_ you try the code! */\r
140   \r
141    // set port C output enable (so we can handle the JTAG enable signal)\r
142    OEC = (1 << 7);\r
143 \r
144    // set port E output enable (actually only PE6 is used to enable/disable the 1.2V regulator, but for strange reasons we also have to enable PE1-5)\r
145    OEE = 0x7F;\r
146 \r
147    // disconnect the 1.2V converter (in the configuration process, we can not draw\r
148    // more than 100ma)\r
149    IOE = (1 << 6);\r
150 \r
151    // set the CPU clock to 48MHz\r
152    CPUCS = bmCLKSPD1;\r
153 \r
154    // activate JTAG outputs on Port C\r
155    OEC = bmTDIOE | bmTCKOE | bmTMSOE | bmJTAG_EN;\r
156 \r
157    // put the system in FIFO mode by default\r
158    // internal clock source at 48Mhz, drive output pin, synchronous mode\r
159    // NOTE: Altera USB-Blaster does not work in another mode\r
160    IFCONFIG =  bmIFCLKSRC | bm3048MHZ | bmIFCLKOE;\r
161    IFCONFIG |= bmASYNC | bmIFCFG1 | bmIFCFG0;\r
162 }\r
163 \r
164 void ProgIO_Set_State(unsigned char d)\r
165 {\r
166   /* Set state of output pins:\r
167    *\r
168    * d.0 => TCK\r
169    * d.1 => TMS\r
170    * d.2 => nCE (only #ifdef HAVE_AS_MODE)\r
171    * d.3 => nCS (only #ifdef HAVE_AS_MODE)\r
172    * d.4 => TDI\r
173    * d.6 => LED / Output Enable\r
174    */\r
175 \r
176   SetTCK((d & bmBIT0) ? 1 : 0);\r
177   SetTMS((d & bmBIT1) ? 1 : 0);\r
178 #ifdef HAVE_AS_MODE\r
179   SetNCE((d & bmBIT2) ? 1 : 0);\r
180   SetNCS((d & bmBIT3) ? 1 : 0);\r
181 #endif\r
182   SetTDI((d & bmBIT4) ? 1 : 0);\r
183 #ifdef HAVE_OE_LED\r
184   SetOELED((d & bmBIT5) ? 1 : 0);\r
185 #endif\r
186 }\r
187 \r
188 unsigned char ProgIO_Set_Get_State(unsigned char d)\r
189 {\r
190   ProgIO_Set_State(d);\r
191 \r
192   /* Read state of input pins:\r
193    *\r
194    * TDO => d.0\r
195    * DATAOUT => d.1 (only #ifdef HAVE_AS_MODE)\r
196    */\r
197 \r
198    return (GetASDO()<<1)|GetTDO();\r
199 }\r
200 \r
201 //-----------------------------------------------------------------------------\r
202 \r
203 void ProgIO_ShiftOut(unsigned char c)\r
204 {\r
205   /* Shift out byte C: \r
206    *\r
207    * 8x {\r
208    *   Output least significant bit on TDI\r
209    *   Raise TCK\r
210    *   Shift c right\r
211    *   Lower TCK\r
212    * }\r
213    */\r
214  \r
215   (void)c; /* argument passed in DPL */\r
216 \r
217   _asm\r
218         MOV  A,DPL\r
219         ;; Bit0\r
220         RRC  A\r
221         MOV  _TDI,C\r
222         SETB _TCK\r
223         ;; Bit1\r
224         RRC  A\r
225         CLR  _TCK\r
226         MOV  _TDI,C\r
227         SETB _TCK\r
228         ;; Bit2\r
229         RRC  A\r
230         CLR  _TCK\r
231         MOV  _TDI,C\r
232         SETB _TCK\r
233         ;; Bit3\r
234         RRC  A\r
235         CLR  _TCK\r
236         MOV  _TDI,C\r
237         SETB _TCK\r
238         ;; Bit4\r
239         RRC  A\r
240         CLR  _TCK\r
241         MOV  _TDI,C\r
242         SETB _TCK\r
243         ;; Bit5\r
244         RRC  A\r
245         CLR  _TCK\r
246         MOV  _TDI,C\r
247         SETB _TCK\r
248         ;; Bit6\r
249         RRC  A\r
250         CLR  _TCK\r
251         MOV  _TDI,C\r
252         SETB _TCK\r
253         ;; Bit7\r
254         RRC  A\r
255         CLR  _TCK\r
256         MOV  _TDI,C\r
257         SETB _TCK\r
258         NOP \r
259         CLR  _TCK\r
260         ret\r
261   _endasm;\r
262 }\r
263 \r
264 /*\r
265 ;; For ShiftInOut, the timing is a little more\r
266 ;; critical because we have to read _TDO/shift/set _TDI\r
267 ;; when _TCK is low. But 20% duty cycle at 48/4/5 MHz\r
268 ;; is just like 50% at 6 Mhz, and that's still acceptable\r
269 */\r
270 \r
271 #if HAVE_AS_MODE\r
272 \r
273 unsigned char ProgIO_ShiftInOut_JTAG(unsigned char c);\r
274 unsigned char ProgIO_ShiftInOut_AS(unsigned char c);\r
275 \r
276 unsigned char ProgIO_ShiftInOut(unsigned char c)\r
277 {\r
278   if(GetNCS(x)) return ProgIO_ShiftInOut_JTAG(c);\r
279   return ProgIO_ShiftInOut_AS(c);\r
280 }\r
281 \r
282 #else /* HAVE_AS_MODE */\r
283 \r
284 #define ProgIO_ShiftInOut_JTAG(x) ProgIO_ShiftInOut(x)\r
285 \r
286 #endif\r
287 \r
288 unsigned char ProgIO_ShiftInOut_JTAG(unsigned char c)\r
289 {\r
290   /* Shift out byte C, shift in from TDO:\r
291    *\r
292    * 8x {\r
293    *   Read carry from TDO\r
294    *   Output least significant bit on TDI\r
295    *   Raise TCK\r
296    *   Shift c right, append carry (TDO) at left\r
297    *   Lower TCK\r
298    * }\r
299    * Return c.\r
300    */\r
301 \r
302    (void)c; /* argument passed in DPL */\r
303 \r
304   _asm\r
305         MOV  A,DPL\r
306 \r
307         ;; Bit0\r
308         MOV  C,_TDO\r
309         RRC  A\r
310         MOV  _TDI,C\r
311         SETB _TCK\r
312         CLR  _TCK\r
313         ;; Bit1\r
314         MOV  C,_TDO\r
315         RRC  A\r
316         MOV  _TDI,C\r
317         SETB _TCK\r
318         CLR  _TCK\r
319         ;; Bit2\r
320         MOV  C,_TDO\r
321         RRC  A\r
322         MOV  _TDI,C\r
323         SETB _TCK\r
324         CLR  _TCK\r
325         ;; Bit3\r
326         MOV  C,_TDO\r
327         RRC  A\r
328         MOV  _TDI,C\r
329         SETB _TCK\r
330         CLR  _TCK\r
331         ;; Bit4\r
332         MOV  C,_TDO\r
333         RRC  A\r
334         MOV  _TDI,C\r
335         SETB _TCK\r
336         CLR  _TCK\r
337         ;; Bit5\r
338         MOV  C,_TDO\r
339         RRC  A\r
340         MOV  _TDI,C\r
341         SETB _TCK\r
342         CLR  _TCK\r
343         ;; Bit6\r
344         MOV  C,_TDO\r
345         RRC  A\r
346         MOV  _TDI,C\r
347         SETB _TCK\r
348         CLR  _TCK\r
349         ;; Bit7\r
350         MOV  C,_TDO\r
351         RRC  A\r
352         MOV  _TDI,C\r
353         SETB _TCK\r
354         CLR  _TCK\r
355 \r
356         MOV  DPL,A\r
357         ret\r
358   _endasm;\r
359 \r
360   /* return value in DPL */\r
361 \r
362   return c;\r
363 }\r
364 \r
365 #ifdef HAVE_AS_MODE\r
366 \r
367 unsigned char ProgIO_ShiftInOut_AS(unsigned char c)\r
368 {\r
369   /* Shift out byte C, shift in from TDO:\r
370    *\r
371    * 8x {\r
372    *   Read carry from TDO\r
373    *   Output least significant bit on TDI\r
374    *   Raise TCK\r
375    *   Shift c right, append carry (TDO) at left\r
376    *   Lower TCK\r
377    * }\r
378    * Return c.\r
379    */\r
380 \r
381   (void)c; /* argument passed in DPL */\r
382 \r
383   _asm\r
384         MOV  A,DPL\r
385 \r
386         ;; Bit0\r
387         MOV  C,_ASDO\r
388         RRC  A\r
389         MOV  _TDI,C\r
390         SETB _TCK\r
391         CLR  _TCK\r
392         ;; Bit1\r
393         MOV  C,_ASDO\r
394         RRC  A\r
395         MOV  _TDI,C\r
396         SETB _TCK\r
397         CLR  _TCK\r
398         ;; Bit2\r
399         MOV  C,_ASDO\r
400         RRC  A\r
401         MOV  _TDI,C\r
402         SETB _TCK\r
403         CLR  _TCK\r
404         ;; Bit3\r
405         MOV  C,_ASDO\r
406         RRC  A\r
407         MOV  _TDI,C\r
408         SETB _TCK\r
409         CLR  _TCK\r
410         ;; Bit4\r
411         MOV  C,_ASDO\r
412         RRC  A\r
413         MOV  _TDI,C\r
414         SETB _TCK\r
415         CLR  _TCK\r
416         ;; Bit5\r
417         MOV  C,_ASDO\r
418         RRC  A\r
419         MOV  _TDI,C\r
420         SETB _TCK\r
421         CLR  _TCK\r
422         ;; Bit6\r
423         MOV  C,_ASDO\r
424         RRC  A\r
425         MOV  _TDI,C\r
426         SETB _TCK\r
427         CLR  _TCK\r
428         ;; Bit7\r
429         MOV  C,_ASDO\r
430         RRC  A\r
431         MOV  _TDI,C\r
432         SETB _TCK\r
433         CLR  _TCK\r
434 \r
435         MOV  DPL,A\r
436         ret\r
437   _endasm;\r
438   return c;\r
439 }\r
440 \r
441 #endif /* HAVE_AS_MODE */\r
442 \r
443 \r