14e87617edd1a48e57b32c658b9b345ff6870a79
[goodfet] / firmware / apps / jtag / jtag.c
1 //GoodFET JTAG Application
2 //Handles basic I/O
3
4 //Higher level left to client application.
5
6 #include "platform.h"
7 #include "command.h"
8 #include "jtag.h"
9
10
11 //! Set up the pins for JTAG mode.
12 void jtagsetup(){
13   P5DIR|=MOSI+SCK+TMS;
14   P5DIR&=~MISO;
15   P5OUT|=0xFFFF;
16   P5OUT=0;
17   P4DIR|=TST;
18   P2DIR|=RST;
19   msdelay(100);
20 }
21
22 int savedtclk=0;
23 //! Shift 8 bits in and out.
24 unsigned char jtagtrans8(unsigned char byte){
25   unsigned int bit;
26   SAVETCLK;
27   for (bit = 0; bit < 8; bit++) {
28     /* write MOSI on trailing edge of previous clock */
29     if (byte & 0x80)
30       {SETMOSI;}
31     else
32       {CLRMOSI;}
33     byte <<= 1;
34     
35     if(bit==7)
36       SETTMS;//TMS high on last bit to exit.
37     
38     CLRTCK;
39     SETTCK;
40      /* read MISO on trailing edge */
41     byte |= READMISO;
42   }
43   RESTORETCLK;
44   
45   // exit state
46   CLRTCK;
47   SETTCK;
48   // update state
49   CLRTMS;
50   CLRTCK;
51   SETTCK;
52   
53   return byte;
54 }
55
56 //! Shift n bits in and out.
57 unsigned long jtagtransn(unsigned long word,
58                          unsigned int bitcount){
59   unsigned int bit;
60   //0x8000
61   unsigned long high;
62   
63   if(bitcount==20)
64     high=0x80000;
65   if(bitcount==16)
66     high= 0x8000;
67   
68   SAVETCLK;
69   
70   for (bit = 0; bit < bitcount; bit++) {
71     /* write MOSI on trailing edge of previous clock */
72     if (word & high)
73       {SETMOSI;}
74     else
75       {CLRMOSI;}
76     word <<= 1;
77     
78     if(bit==bitcount-1)
79       SETTMS;//TMS high on last bit to exit.
80     
81     CLRTCK;
82     SETTCK;
83     /* read MISO on trailing edge */
84     word |= READMISO;
85   }
86   
87   if(bitcount==20){
88     word = ((word << 16) | (word >> 4)) & 0x000FFFFF;
89   }
90   
91   RESTORETCLK;
92   
93   // exit state
94   CLRTCK;
95   SETTCK;
96   // update state
97   CLRTMS;
98   CLRTCK;
99   SETTCK;
100   
101   return word;
102 }
103
104 /*
105 //! Shift 16 bits in and out.
106 unsigned int jtagtrans16(unsigned int word){ //REMOVEME
107   unsigned int bit;
108   SAVETCLK;
109   
110   for (bit = 0; bit < 16; bit++) {
111     // write MOSI on trailing edge of previous clock 
112     if (word & 0x8000)
113       {SETMOSI;}
114     else
115       {CLRMOSI;}
116     word <<= 1;
117     
118     if(bit==15)
119       SETTMS;//TMS high on last bit to exit.
120     
121     CLRTCK;
122     SETTCK;
123     // read MISO on trailing edge 
124     word |= READMISO;
125   }
126   RESTORETCLK;
127   
128   // exit state
129   CLRTCK;
130   SETTCK;
131   // update state
132   CLRTMS;
133   CLRTCK;
134   SETTCK;
135   
136   return word;
137 }*/
138
139 //! Stop JTAG, release pins
140 void jtag_stop(){
141   P5OUT=0;
142   P4OUT=0;
143 }
144
145 unsigned int drwidth=20;
146 //! Shift all bits of the DR.
147 unsigned long jtag_dr_shift20(unsigned long in){
148   // idle
149   SETTMS;
150   CLRTCK;
151   SETTCK;
152   // select DR
153   CLRTMS;
154   CLRTCK;
155   SETTCK;
156   // capture IR
157   CLRTCK;
158   SETTCK;
159   
160   // shift DR, then idle
161   return(jtagtransn(in,20));
162 }
163
164
165 //! Shift 16 bits of the DR.
166 unsigned int jtag_dr_shift16(unsigned int in){
167   // idle
168   SETTMS;
169   CLRTCK;
170   SETTCK;
171   // select DR
172   CLRTMS;
173   CLRTCK;
174   SETTCK;
175   // capture IR
176   CLRTCK;
177   SETTCK;
178   
179   // shift DR, then idle
180   return(jtagtransn(in,16));
181 }
182
183
184 //! Shift 8 bits of the IR.
185 unsigned char jtag_ir_shift8(unsigned char in){
186   // idle
187   SETTMS;
188   CLRTCK;
189   SETTCK;
190   // select DR
191   CLRTCK;
192   SETTCK;
193   // select IR
194   CLRTMS;
195   CLRTCK;
196   SETTCK;
197   // capture IR
198   CLRTCK;
199   SETTCK;
200   
201   // shift IR, then idle.
202   return(jtagtrans8(in));
203 }
204
205 //! Handles a monitor command.
206 void jtaghandle(unsigned char app,
207                unsigned char verb,
208                unsigned char len){
209   switch(verb){
210     //START handled by specific JTAG
211   case STOP:
212     jtag_stop();
213     txdata(app,verb,0);
214     break;
215   case SETUP:
216     jtagsetup();
217     txdata(app,verb,0);
218     break;
219   case JTAG_IR_SHIFT:
220     cmddata[0]=jtag_ir_shift8(cmddata[0]);
221     txdata(app,verb,1);
222     break;
223   case JTAG_DR_SHIFT:
224     cmddataword[0]=jtag_dr_shift16(cmddataword[0]);
225     txdata(app,verb,2);
226     break;
227   default:
228     txdata(app,NOK,0);
229   }
230 }
231
232