215ab9967f90083fe79b7d5d0d03b55711c2a818
[goodfet] / firmware / apps / jtag / jtag430.c
1 /*! \file jtag430.c
2   \author Travis Goodspeed <travis at radiantmachines.com>
3   
4   This is an implementation of the 16-bit MSP430 JTAG protocol
5   for the GoodFET project at http://goodfet.sf.net/
6   
7   See the license file for details of proper use.
8 */
9
10 #include "platform.h"
11 #include "command.h"
12 #include "jtag.h"
13
14
15 unsigned int jtag430mode=MSP430X2MODE;
16
17 //! Set the program counter.
18 void jtag430_setpc(unsigned int adr){
19   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
20   jtag_dr_shift16(0x3401);// release low byte
21   jtag_ir_shift8(IR_DATA_16BIT);
22   jtag_dr_shift16(0x4030);//Instruction to load PC
23   CLRTCLK;
24   SETTCLK;
25   jtag_dr_shift16(adr);// Value for PC
26   CLRTCLK;
27   jtag_ir_shift8(IR_ADDR_CAPTURE);
28   SETTCLK;
29   CLRTCLK ;// Now PC is set to "PC_Value"
30   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
31   jtag_dr_shift16(0x2401);// low byte controlled by JTAG
32 }
33
34 //! Halt the CPU
35 void jtag430_haltcpu(){
36   //jtag430_setinstrfetch();
37   
38   jtag_ir_shift8(IR_DATA_16BIT);
39   jtag_dr_shift16(0x3FFF);//JMP $+0
40   
41   CLRTCLK;
42   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
43   jtag_dr_shift16(0x2409);//set JTAG_HALT bit
44   SETTCLK;
45 }
46
47 //! Release the CPU
48 void jtag430_releasecpu(){
49   CLRTCLK;
50   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
51   jtag_dr_shift16(0x2401);
52   jtag_ir_shift8(IR_ADDR_CAPTURE);
53   SETTCLK;
54 }
55
56 //! Read data from address
57 unsigned int jtag430_readmem(unsigned int adr){
58   unsigned int toret;
59   
60   CLRTCLK;
61   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
62   
63   if(adr>0xFF)
64     jtag_dr_shift16(0x2409);//word read
65   else
66     jtag_dr_shift16(0x2419);//byte read
67   jtag_ir_shift8(IR_ADDR_16BIT);
68   jtag_dr_shift16(adr);//address
69   jtag_ir_shift8(IR_DATA_TO_ADDR);
70   SETTCLK;
71
72   CLRTCLK;
73   toret=jtag_dr_shift16(0x0000);//16 bit return
74   
75   return toret;
76 }
77
78 //! Write data to address.
79 void jtag430_writemem(unsigned int adr, unsigned int data){
80   CLRTCLK;
81   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
82   if(adr>0xFF)
83     jtag_dr_shift16(0x2408);//word write
84   else
85     jtag_dr_shift16(0x2418);//byte write
86   jtag_ir_shift8(IR_ADDR_16BIT);
87   jtag_dr_shift16(adr);
88   jtag_ir_shift8(IR_DATA_TO_ADDR);
89   jtag_dr_shift16(data);
90   SETTCLK;
91 }
92
93 //! Write data to flash memory.  Must be preconfigured.
94 void jtag430_writeflashword(unsigned int adr, unsigned int data){
95   /*
96   CLRTCLK;
97   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
98   jtag_dr_shift16(0x2408);//word write
99   jtag_ir_shift8(IR_ADDR_16BIT);
100   jtag_dr_shift16(adr);
101   jtag_ir_shift8(IR_DATA_TO_ADDR);
102   jtag_dr_shift16(data);
103   SETTCLK;
104   
105   //Return to read mode.
106   CLRTCLK;
107   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
108   jtag_dr_shift16(0x2409);
109   */
110   
111   jtag430_writemem(adr,data);
112   CLRTCLK;
113   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
114   jtag_dr_shift16(0x2409);
115   
116   //Pulse TCLK
117   jtag430_tclk_flashpulses(35); //35 standard
118   
119 }
120
121 //! Configure flash, then write a word.
122 void jtag430_writeflash(unsigned int adr, unsigned int data){
123   jtag430_haltcpu();
124   
125   //FCTL1=0xA540, enabling flash write
126   jtag430_writemem(0x0128, 0xA540);
127   //FCTL2=0xA540, selecting MCLK as source, DIV=1
128   jtag430_writemem(0x012A, 0xA540);
129   //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
130   jtag430_writemem(0x012C, 0xA500);
131   
132   //Write the word itself.
133   jtag430_writeflashword(adr,data);
134   
135   //FCTL1=0xA500, disabling flash write
136   jtag430_writemem(0x0128, 0xA500);
137   
138   jtag430_releasecpu();
139 }
140
141
142
143 //! Power-On Reset
144 void jtag430_por(){
145   unsigned int jtagid;
146
147   // Perform Reset
148   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
149   jtag_dr_shift16(0x2C01); // apply
150   jtag_dr_shift16(0x2401); // remove
151   CLRTCLK;
152   SETTCLK;
153   CLRTCLK;
154   SETTCLK;
155   CLRTCLK;
156   jtagid = jtag_ir_shift8(IR_ADDR_CAPTURE); // get JTAG identifier
157   SETTCLK;
158   
159   jtag430_writemem(0x0120, 0x5A80);   // Diabled Watchdog
160 }
161
162
163
164 #define ERASE_GLOB 0xA50E
165 #define ERASE_ALLMAIN 0xA50C
166 #define ERASE_MASS 0xA506
167 #define ERASE_MAIN 0xA504
168 #define ERASE_SGMT 0xA502
169
170 //! Configure flash, then write a word.
171 void jtag430_eraseflash(unsigned int mode, unsigned int adr, unsigned int count){
172   jtag430_haltcpu();
173   
174   //FCTL1= erase mode
175   jtag430_writemem(0x0128, mode);
176   //FCTL2=0xA540, selecting MCLK as source, DIV=1
177   jtag430_writemem(0x012A, 0xA540);
178   //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
179   jtag430_writemem(0x012C, 0xA500);
180   
181   //Write the erase word.
182   jtag430_writemem(adr, 0x55AA);
183   //Return to read mode.
184   CLRTCLK;
185   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
186   jtag_dr_shift16(0x2409);
187   
188   //Send the pulses.
189   jtag430_tclk_flashpulses(count);
190   
191   //FCTL1=0xA500, disabling flash write
192   jtag430_writemem(0x0128, 0xA500);
193   
194   jtag430_releasecpu();
195 }
196
197
198 //! Reset the TAP state machine.
199 void jtag430_resettap(){
200   int i;
201   // Settle output
202   SETTDI; //430X2
203   SETTMS;
204   //SETTDI; //classic
205   SETTCK;
206
207   // Navigate to reset state.
208   // Should be at least six.
209   for(i=0;i<4;i++){
210     CLRTCK;
211     SETTCK;
212   }
213
214   // test-logic-reset
215   CLRTCK;
216   CLRTMS;
217   SETTCK;
218   SETTMS;
219   // idle
220
221     
222   /* sacred, by spec.
223      Sometimes this isn't necessary.  */
224   // fuse check
225   CLRTMS;
226   delay(50);
227   SETTMS;
228   CLRTMS;
229   delay(50);
230   SETTMS;
231   /**/
232   
233 }
234
235 //! Start JTAG, take pins
236 void jtag430_start(){
237   jtagsetup();
238   
239   //Known-good starting position.
240   //Might be unnecessary.
241   SETTST;
242   SETRST;
243   delay(0xFFFF);
244   
245   //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 JTAG
246   CLRRST;
247   delay(100);
248   CLRTST;
249   delay(50);
250   SETTST;
251   delay(50);
252   SETRST;
253   P5DIR&=~RST;
254   delay(0xFFFF);
255   
256   //Perform a reset and disable watchdog.
257   jtag430_por();
258 }
259
260 //! Set CPU to Instruction Fetch
261 void jtag430_setinstrfetch(){
262   jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
263
264   // Wait until instruction fetch state.
265   while(1){
266     if (jtag_dr_shift16(0x0000) & 0x0080)
267       return;
268     CLRTCLK;
269     SETTCLK;
270   }
271 }
272
273
274 //! Handles classic MSP430 JTAG commands.  Forwards others to JTAG.
275 void oldjtag430handle(unsigned char app,
276                    unsigned char verb,
277                    unsigned char len){
278   
279   switch(verb){
280   case START:
281     //Enter JTAG mode.
282     jtag430_start();
283     //TAP setup, fuse check
284     jtag430_resettap();
285     
286     txdata(app,verb,0);
287     break;
288   case JTAG430_HALTCPU:
289     jtag430_haltcpu();
290     txdata(app,verb,0);
291     break;
292   case JTAG430_RELEASECPU:
293     jtag430_releasecpu();
294     txdata(app,verb,0);
295     break;
296   case JTAG430_SETINSTRFETCH:
297     jtag430_setinstrfetch();
298     txdata(app,verb,0);
299     break;
300     
301   case JTAG430_READMEM:
302   case PEEK:
303     cmddataword[0]=jtag430_readmem(cmddataword[0]);
304     txdata(app,verb,2);
305     break;
306   case JTAG430_WRITEMEM:
307   case POKE:
308     jtag430_writemem(cmddatalong[0],cmddataword[2]);
309     cmddataword[0]=jtag430_readmem(cmddatalong[0]);
310     txdata(app,verb,2);
311     break;
312   case JTAG430_WRITEFLASH:
313     jtag430_writeflash(cmddataword[0],cmddataword[1]);
314     cmddataword[0]=jtag430_readmem(cmddataword[0]);
315     txdata(app,verb,2);
316     break;
317   case JTAG430_ERASEFLASH:
318     jtag430_eraseflash(ERASE_MASS,0xFFFE,0xFFFF);
319     jtag430_eraseflash(ERASE_MASS,0xFFFE,0xFFFF);
320     jtag430_eraseflash(ERASE_MASS,0xFFFE,0xFFFF);
321     txdata(app,verb,0);
322     break;
323   case JTAG430_SETPC:
324     jtag430_setpc(cmddataword[0]);
325     txdata(app,verb,0);
326     break;
327   default:
328     jtaghandle(app,verb,len);
329   }
330   jtag430_resettap();
331 }
332
333 //! Handles unique MSP430 JTAG commands.  Forwards others to JTAG.
334 void jtag430handle(unsigned char app,
335                    unsigned char verb,
336                    unsigned char len){
337   switch(jtag430mode){
338   case MSP430MODE:
339     return oldjtag430handle(app,verb,len);
340   case MSP430X2MODE:
341     return jtag430x2handle(app,verb,len);
342   default:
343     txdata(app,NOK,0);
344   }
345 }