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