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