still working on it
[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   /*
17   P5OUT|=0xFFFF;
18   P5OUT=0;
19   */
20   P4DIR|=TST;
21   P2DIR|=RST;
22   msdelay(100);
23 }
24
25 int savedtclk=0;
26 //! Shift 8 bits in and out.
27 unsigned char jtagtrans8(unsigned char byte){
28   unsigned int bit;
29   SAVETCLK;
30   for (bit = 0; bit < 8; bit++) {
31     /* write MOSI on trailing edge of previous clock */
32     if (byte & 0x80)
33       {SETMOSI;}
34     else
35       {CLRMOSI;}
36     byte <<= 1;
37     
38     if(bit==7)
39       SETTMS;//TMS high on last bit to exit.
40     
41     TCKTOCK;
42     /* read MISO on trailing edge */
43     byte |= READMISO;
44   }
45   RESTORETCLK;
46   
47   // exit state
48   TCKTOCK;
49   // update state
50   CLRTMS;
51   TCKTOCK;
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=0x8000;
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     TCKTOCK;
82     /* read MISO on trailing edge */
83     word |= READMISO;
84   }
85   
86   if(bitcount==20){
87     word = ((word << 16) | (word >> 4)) & 0x000FFFFF;
88   }
89   
90   RESTORETCLK;
91   
92   // exit state
93   TCKTOCK;
94   // update state
95   CLRTMS;
96   TCKTOCK;
97   
98   return word;
99 }
100
101
102 //! Stop JTAG, release pins
103 void jtag_stop(){
104   P5OUT=0;
105   P4OUT=0;
106 }
107
108 unsigned int drwidth=16;
109 //! Shift all bits of the DR.
110 unsigned long jtag_dr_shift20(unsigned long in){
111   // idle
112   SETTMS;
113   TCKTOCK;
114   // select DR
115   CLRTMS;
116   TCKTOCK;
117   // capture IR
118   TCKTOCK;
119   
120   // shift DR, then idle
121   return(jtagtransn(in,20));
122 }
123
124
125 //! Shift 16 bits of the DR.
126 unsigned int jtag_dr_shift16(unsigned int in){
127   // idle
128   SETTMS;
129   TCKTOCK;
130   // select DR
131   CLRTMS;
132   TCKTOCK;
133   // capture IR
134   TCKTOCK;
135   
136   // shift DR, then idle
137   return(jtagtransn(in,16));
138 }
139
140 //! Shift native width of the DR
141 unsigned long jtag_dr_shiftadr(unsigned long in){
142   unsigned long out=0;
143   
144   // idle
145   SETTMS;
146   TCKTOCK;
147   // select DR
148   CLRTMS;
149   TCKTOCK;
150   // capture IR
151   TCKTOCK;
152
153   
154   out=jtagtransn(in,drwidth);
155   
156   // shift DR, then idle
157   return(out);
158 }
159
160
161 //! Shift 8 bits of the IR.
162 unsigned char jtag_ir_shift8(unsigned char in){
163   // idle
164   SETTMS;
165   TCKTOCK;
166   // select DR
167   TCKTOCK;
168   // select IR
169   CLRTMS;
170   TCKTOCK;
171   // capture IR
172   TCKTOCK;
173   
174   // shift IR, then idle.
175   return(jtagtrans8(in));
176 }
177
178 //! Handles a monitor command.
179 void jtaghandle(unsigned char app,
180                unsigned char verb,
181                unsigned long len){
182   switch(verb){
183     //START handled by specific JTAG
184   case STOP:
185     jtag_stop();
186     txdata(app,verb,0);
187     break;
188   case SETUP:
189     jtagsetup();
190     txdata(app,verb,0);
191     break;
192   case JTAG_IR_SHIFT:
193     cmddata[0]=jtag_ir_shift8(cmddata[0]);
194     txdata(app,verb,1);
195     break;
196   case JTAG_DR_SHIFT:
197     cmddataword[0]=jtag_dr_shift16(cmddataword[0]);
198     txdata(app,verb,2);
199     break;
200   default:
201     txdata(app,NOK,0);
202   }
203 }
204
205