16-bit MSP430 Flash writing works again on 1612-based GoodFETs.
[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   
56   CLRTCLK;
57   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
58   
59   if(adr>0xFF)
60     jtag_dr_shift16(0x2409);//word read
61   else
62     jtag_dr_shift16(0x2419);//byte read
63   jtag_ir_shift8(IR_ADDR_16BIT);
64   jtag_dr_shift16(adr);//address
65   jtag_ir_shift8(IR_DATA_TO_ADDR);
66   SETTCLK;
67
68   CLRTCLK;
69   toret=jtag_dr_shift16(0x0000);//16 bit return
70   
71   return toret;
72 }
73
74 //! Write data to address.
75 void jtag430_writemem(unsigned int adr, unsigned int data){
76   CLRTCLK;
77   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
78   if(adr>0xFF)
79     jtag_dr_shift16(0x2408);//word write
80   else
81     jtag_dr_shift16(0x2418);//byte write
82   jtag_ir_shift8(IR_ADDR_16BIT);
83   jtag_dr_shift16(adr);
84   jtag_ir_shift8(IR_DATA_TO_ADDR);
85   jtag_dr_shift16(data);
86   SETTCLK;
87 }
88
89 //! Write data to flash memory.  Must be preconfigured.
90 void jtag430_writeflashword(unsigned int adr, unsigned int data){
91   
92   CLRTCLK;
93   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
94   jtag_dr_shift16(0x2408);//word write
95   jtag_ir_shift8(IR_ADDR_16BIT);
96   jtag_dr_shift16(adr);
97   jtag_ir_shift8(IR_DATA_TO_ADDR);
98   jtag_dr_shift16(data);
99   SETTCLK;
100   
101   //Return to read mode.
102   CLRTCLK;
103   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
104   jtag_dr_shift16(0x2409);
105   
106   /*
107   jtag430_writemem(adr,data);
108   CLRTCLK;
109   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
110   jtag_dr_shift16(0x2409);
111   */
112   
113   //Pulse TCLK
114   jtag430_tclk_flashpulses(35); //35 standard
115   
116 }
117
118 //! Configure flash, then write a word.
119 void jtag430_writeflash(unsigned int adr, unsigned int data){
120   jtag430_haltcpu();
121   
122   //FCTL1=0xA540, enabling flash write
123   jtag430_writemem(0x0128, 0xA540);
124   //FCTL2=0xA540, selecting MCLK as source, DIV=1
125   jtag430_writemem(0x012A, 0xA540);
126   //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
127   jtag430_writemem(0x012C, 0xA500); //all but info flash.
128   
129   //Write the word itself.
130   jtag430_writeflashword(adr,data);
131   
132   //FCTL1=0xA500, disabling flash write
133   jtag430_writemem(0x0128, 0xA500);
134   
135   jtag430_releasecpu();
136 }
137
138
139
140 //! Power-On Reset
141 void jtag430_por(){
142   unsigned int jtagid;
143
144   // Perform Reset
145   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
146   jtag_dr_shift16(0x2C01); // apply
147   jtag_dr_shift16(0x2401); // remove
148   CLRTCLK;
149   SETTCLK;
150   CLRTCLK;
151   SETTCLK;
152   CLRTCLK;
153   jtagid = jtag_ir_shift8(IR_ADDR_CAPTURE); // get JTAG identifier
154   SETTCLK;
155   
156   jtag430_writemem(0x0120, 0x5A80);   // Diabled Watchdog
157 }
158
159
160
161 #define ERASE_GLOB 0xA50E
162 #define ERASE_ALLMAIN 0xA50C
163 #define ERASE_MASS 0xA506
164 #define ERASE_MAIN 0xA504
165 #define ERASE_SGMT 0xA502
166
167 //! Configure flash, then write a word.
168 void jtag430_eraseflash(unsigned int mode, unsigned int adr, unsigned int count){
169   jtag430_haltcpu();
170   
171   //FCTL1= erase mode
172   jtag430_writemem(0x0128, mode);
173   //FCTL2=0xA540, selecting MCLK as source, DIV=1
174   jtag430_writemem(0x012A, 0xA540);
175   //FCTL3=0xA500, should be 0xA540 for Info Seg A on 2xx chips.
176   jtag430_writemem(0x012C, 0xA500);
177   
178   //Write the erase word.
179   jtag430_writemem(adr, 0x55AA);
180   //Return to read mode.
181   CLRTCLK;
182   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
183   jtag_dr_shift16(0x2409);
184   
185   //Send the pulses.
186   jtag430_tclk_flashpulses(count);
187   
188   //FCTL1=0xA500, disabling flash write
189   jtag430_writemem(0x0128, 0xA500);
190   
191   jtag430_releasecpu();
192 }
193
194
195 //! Reset the TAP state machine.
196 void jtag430_resettap(){
197   int i;
198   // Settle output
199   SETTDI; //430X2
200   SETTMS;
201   //SETTDI; //classic
202   SETTCK;
203
204   // Navigate to reset state.
205   // Should be at least six.
206   for(i=0;i<4;i++){
207     CLRTCK;
208     SETTCK;
209   }
210
211   // test-logic-reset
212   CLRTCK;
213   CLRTMS;
214   SETTCK;
215   SETTMS;
216   // idle
217
218     
219   /* sacred, by spec.
220      Sometimes this isn't necessary.  */
221   // fuse check
222   CLRTMS;
223   delay(50);
224   SETTMS;
225   CLRTMS;
226   delay(50);
227   SETTMS;
228   /**/
229   
230 }
231
232 //! Start JTAG, take pins
233 void jtag430_start(){
234   jtagsetup();
235   
236   //Known-good starting position.
237   //Might be unnecessary.
238   SETTST;
239   SETRST;
240   delay(0xFFFF);
241   
242   //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 JTAG
243   CLRRST;
244   delay(100); //100
245   CLRTST;
246   delay(50);  //50
247   SETTST;
248   delay(50);  //50
249   SETRST;
250   P5DIR&=~RST;
251   delay(0xFFFF);
252   
253   //Perform a reset and disable watchdog.
254   jtag430_por();
255 }
256
257 //! Set CPU to Instruction Fetch
258 void jtag430_setinstrfetch(){
259   jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
260
261   // Wait until instruction fetch state.
262   while(1){
263     if (jtag_dr_shift16(0x0000) & 0x0080)
264       return;
265     CLRTCLK;
266     SETTCLK;
267   }
268 }
269
270
271 //! Handles classic MSP430 JTAG commands.  Forwards others to JTAG.
272 void jtag430handle(unsigned char app,
273                    unsigned char verb,
274                    unsigned char len){
275   register char blocks;
276   unsigned long at;
277   unsigned int i, val;
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     /*
304     cmddataword[0]=jtag430_readmem(cmddataword[0]);
305     txdata(app,verb,2);
306     */
307     blocks=(len>4?cmddata[4]:1);
308     at=cmddatalong[0];
309     
310     len=0x80;
311     serial_tx(app);
312     serial_tx(verb);
313     serial_tx(len);
314     
315     while(blocks--){
316       for(i=0;i<len;i+=2){
317         jtag430_resettap();
318         delay(10);
319         
320         val=jtag430_readmem(at);
321                 
322         at+=2;
323         serial_tx(val&0xFF);
324         serial_tx((val&0xFF00)>>8);
325       }
326     }
327     
328     
329     
330     break;
331   case JTAG430_WRITEMEM:
332   case POKE:
333     jtag430_writemem(cmddataword[0],cmddataword[2]);
334     cmddataword[0]=jtag430_readmem(cmddataword[0]);
335     txdata(app,verb,2);
336     break;
337   case JTAG430_WRITEFLASH:
338     debugstr("Poking flash memory.");
339     jtag430_writeflash(cmddataword[0],cmddataword[2]);
340     cmddataword[0]=jtag430_readmem(cmddataword[0]);
341     txdata(app,verb,2);
342     break;
343   case JTAG430_ERASEFLASH:
344     jtag430_eraseflash(ERASE_MASS,0xFFFE,0xFFFF);
345     jtag430_eraseflash(ERASE_MASS,0xFFFE,0xFFFF);
346     jtag430_eraseflash(ERASE_MASS,0xFFFE,0xFFFF);
347     txdata(app,verb,0);
348     break;
349   case JTAG430_SETPC:
350     jtag430_setpc(cmddataword[0]);
351     txdata(app,verb,0);
352     break;
353     
354   case JTAG430_COREIP_ID:
355   case JTAG430_DEVICE_ID:
356     cmddataword[0]=0;
357     cmddataword[1]=0;
358     txdata(app,verb,4);
359     break;
360     
361   default:
362     jtaghandle(app,verb,len);
363   }
364   jtag430_resettap();
365 }