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