Adds upport for some 20-bit MSP430X chips.
[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     TCKTOCK;
40     /* read MISO on trailing edge */
41     byte |= READMISO;
42   }
43   RESTORETCLK;
44   
45   // exit state
46   TCKTOCK;
47   // update state
48   CLRTMS;
49   TCKTOCK;
50   
51   return byte;
52 }
53
54 //! Shift n bits in and out.
55 unsigned long jtagtransn(unsigned long word,
56                          unsigned int bitcount){
57   unsigned int bit;
58   //0x8000
59   unsigned long high=0x8000;
60   
61   if(bitcount==20)
62     high=0x80000;
63   if(bitcount==16)
64     high= 0x8000;
65   
66   SAVETCLK;
67   
68   for (bit = 0; bit < bitcount; bit++) {
69     /* write MOSI on trailing edge of previous clock */
70     if (word & high)
71       {SETMOSI;}
72     else
73       {CLRMOSI;}
74     word <<= 1;
75     
76     if(bit==bitcount-1)
77       SETTMS;//TMS high on last bit to exit.
78     
79     TCKTOCK;
80     /* read MISO on trailing edge */
81     word |= READMISO;
82   }
83   
84   if(bitcount==20){
85     word = ((word << 16) | (word >> 4)) & 0x000FFFFF;
86   }
87   
88   RESTORETCLK;
89   
90   // exit state
91   TCKTOCK;
92   // update state
93   CLRTMS;
94   TCKTOCK;
95   
96   return word;
97 }
98
99
100 //! Stop JTAG, release pins
101 void jtag_stop(){
102   P5OUT=0;
103   P4OUT=0;
104 }
105
106 unsigned int drwidth=16;
107 //! Shift all bits of the DR.
108 unsigned long jtag_dr_shift20(unsigned long in){
109   // idle
110   SETTMS;
111   TCKTOCK;
112   // select DR
113   CLRTMS;
114   TCKTOCK;
115   // capture IR
116   TCKTOCK;
117   
118   // shift DR, then idle
119   return(jtagtransn(in,20));
120 }
121
122
123 //! Shift 16 bits of the DR.
124 unsigned int jtag_dr_shift16(unsigned int in){
125   // idle
126   SETTMS;
127   TCKTOCK;
128   // select DR
129   CLRTMS;
130   TCKTOCK;
131   // capture IR
132   TCKTOCK;
133   
134   // shift DR, then idle
135   return(jtagtransn(in,16));
136 }
137
138 //! Shift native width of the DR
139 unsigned long jtag_dr_shiftadr(unsigned long in){
140   unsigned long out=0;
141   
142   // idle
143   SETTMS;
144   TCKTOCK;
145   // select DR
146   CLRTMS;
147   TCKTOCK;
148   // capture IR
149   TCKTOCK;
150
151   
152   out=jtagtransn(in,drwidth);
153   
154   // shift DR, then idle
155   return(out);
156 }
157
158
159 //! Shift 8 bits of the IR.
160 unsigned char jtag_ir_shift8(unsigned char in){
161   // idle
162   SETTMS;
163   TCKTOCK;
164   // select DR
165   TCKTOCK;
166   // select IR
167   CLRTMS;
168   TCKTOCK;
169   // capture IR
170   TCKTOCK;
171   
172   // shift IR, then idle.
173   return(jtagtrans8(in));
174 }
175
176 //! Handles a monitor command.
177 void jtaghandle(unsigned char app,
178                unsigned char verb,
179                unsigned long len){
180   switch(verb){
181     //START handled by specific JTAG
182   case STOP:
183     jtag_stop();
184     txdata(app,verb,0);
185     break;
186   case SETUP:
187     jtagsetup();
188     txdata(app,verb,0);
189     break;
190   case JTAG_IR_SHIFT:
191     cmddata[0]=jtag_ir_shift8(cmddata[0]);
192     txdata(app,verb,1);
193     break;
194   case JTAG_DR_SHIFT:
195     cmddataword[0]=jtag_dr_shift16(cmddataword[0]);
196     txdata(app,verb,2);
197     break;
198   default:
199     txdata(app,NOK,0);
200   }
201 }
202
203