Repaired MSP430 and MSP430X support.
[goodfet] / firmware / apps / jtag / jtag430x2.c
1 /*! \file jtag430x2.c
2   \author Travis Goodspeed <travis at radiantmachines.com>
3   \brief MSP430X2 JTAG (20-bit)
4 */
5
6 #include "platform.h"
7 #include "command.h"
8 #include "jtag430.h"
9 #include "jtag430x2.h"
10
11 void jtag430x2_handle_fn( uint8_t const app,
12                                                   uint8_t const verb,
13                                                   uint32_t const len);
14
15
16 // define the jtag430x2 app's app_t
17 app_t const jtag430x2_app = {
18
19         /* app number */
20         JTAG430X2,
21
22         /* handle fn */
23         jtag430x2_handle_fn,
24
25         /* name */
26         "JTAG430X2",
27
28         /* desc */
29         "\tThe JTAG430X2 app extends the basic JTAG app with support\n"
30         "\tfor 20-bit MSP430 devices.\n"
31 };
32
33
34
35
36 //! Write data to address
37 void jtag430x2_writemem(unsigned long adr,
38                         unsigned int data){
39   jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
40   if(jtag_dr_shift16(0) & 0x0301){
41     CLRTCLK;
42     jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
43     if(adr>=0x100)
44       jtag_dr_shift16(0x0500);//word mode
45     else
46       jtag_dr_shift16(0x0510);//byte mode
47     jtag_ir_shift8(IR_ADDR_16BIT);
48     jtag_dr_shift20(adr);
49     
50     SETTCLK;
51     
52     jtag_ir_shift8(IR_DATA_TO_ADDR);
53     jtag_dr_shift16(data);//16 word
54
55     CLRTCLK;
56     jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
57     jtag_dr_shift16(0x0501);
58     SETTCLK;
59
60     CLRTCLK;
61     SETTCLK;
62     //init state
63   }else{
64     while(1) PLEDOUT^=PLEDPIN; //loop if locked up
65   }
66 }
67
68 //! Read data from address
69 unsigned int jtag430x2_readmem(unsigned long adr){
70   unsigned int toret=0;
71   //unsigned int tries=5;
72   
73   while(1){
74     //do{
75     jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
76     //}while(!(jtag_dr_shift16(0) & 0x0301));
77     
78     if(jtag_dr_shift16(0) & 0x0301){
79       // Read Memory
80       CLRTCLK;
81       jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
82       
83       //if(adr>=0x100){
84       jtag_dr_shift16(0x0501);//word read
85       //}else{
86       //jtag_dr_shift16(0x0511);//byte read
87       //}
88       
89       jtag_ir_shift8(IR_ADDR_16BIT);
90       jtag_dr_shift20(adr); //20
91       
92       jtag_ir_shift8(IR_DATA_TO_ADDR);
93       SETTCLK;
94       CLRTCLK;
95       toret = jtag_dr_shift16(0x0000);
96       
97       SETTCLK;
98       
99       //Cycle a bit.
100       CLRTCLK;
101       SETTCLK;
102       return toret;
103     }
104   }
105   //return toret;
106 }
107
108 //! Syncs a POR.
109 unsigned int jtag430x2_syncpor(){
110   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
111   jtag_dr_shift16(0x1501); //JTAG mode
112   while(!(jtag_dr_shift16(0) & 0x200));
113   return jtag430x2_por();
114 }
115
116 //! Executes an MSP430X2 POR
117 unsigned int jtag430x2_por(){
118   unsigned int i = 0;
119   
120   // tick
121   CLRTCLK;
122   SETTCLK;
123
124   jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
125   jtag_dr_shift16(0x0C01);
126   jtag_dr_shift16(0x0401);
127   
128   //cycle
129   for (i = 0; i < 10; i++){
130     CLRTCLK;
131     SETTCLK;
132   }
133   
134   jtag_dr_shift16(0x0501);
135   
136   // tick
137   CLRTCLK;
138   SETTCLK;
139   
140   
141   // Disable WDT
142   jtag430x2_writemem(0x015C, 0x5A80);
143   
144   // check state
145   jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
146   if(jtag_dr_shift16(0) & 0x0301)
147     return(1);//ok
148   
149   return 0;//error
150 }
151
152
153 //! Check the fuse.
154 unsigned int jtag430x2_fusecheck(){
155   int i;
156   for(i=0;i<3;i++){
157     jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
158     if(jtag_dr_shift16(0xAAAA)==0x5555)
159       return 1;//blown
160   }
161   return 0;//unblown
162 }
163
164
165 //! Handles MSP430X2 JTAG commands.  Forwards others to JTAG.
166 void jtag430x2_handle_fn( uint8_t const app,
167                                                   uint8_t const verb,
168                                                   uint32_t const len)
169 {
170   register char blocks;
171   
172   unsigned int i,val;
173   unsigned long at, l;
174   
175   //jtag430_resettap();
176   
177   if(verb!=START && jtag430mode==MSP430MODE){
178     (*(jtag430_app.handle))(app,verb,len);
179     return;
180   }
181   
182   switch(verb){
183   case START:
184     //Enter JTAG mode.
185     //do 
186     cmddata[0]=jtag430x2_start();
187     //while(cmddata[0]==00 || cmddata[0]==0xFF);
188     
189     //MSP430 or MSP430X
190     if(jtagid==MSP430JTAGID){ 
191       debugstr("ERROR, using JTAG430X2 instead of JTAG430!");
192       return;
193     }else if(jtagid==MSP430X2JTAGID){
194       jtag430mode=MSP430X2MODE;
195       drwidth=20;
196     }else{
197       debugstr("JTAG version unknown.");
198       txdata(app,NOK,1);
199       return;
200     }
201     
202     jtag430x2_fusecheck();
203         
204     jtag430x2_syncpor();
205     
206     jtag430_resettap();
207     
208     txdata(app,verb,1);
209     break;
210   case JTAG430_READMEM:
211   case PEEK:
212     blocks=(len>4?cmddata[4]:1);
213     at=cmddatalong[0];
214     
215     l=0x80;
216     txhead(app,verb,l);
217     
218     while(blocks--){
219       for(i=0;i<l;i+=2){
220         jtag430_resettap();
221         delay(10);
222         
223         val=jtag430x2_readmem(at);
224                 
225         at+=2;
226         serial_tx(val&0xFF);
227         serial_tx((val&0xFF00)>>8);
228       }
229     }
230     
231     break;
232   case JTAG430_COREIP_ID:
233     cmddataword[0]=jtag430_coreid();
234     txdata(app,verb,2);
235     break;
236   case JTAG430_DEVICE_ID:
237     cmddatalong[0]=jtag430_deviceid();
238     txdata(app,verb,4);
239     break;
240   case JTAG430_WRITEFLASH:
241   case JTAG430_WRITEMEM:
242   case POKE:
243     jtag430x2_writemem(cmddatalong[0],
244                        cmddataword[2]);
245     cmddataword[0]=jtag430x2_readmem(cmddatalong[0]);
246     txdata(app,verb,2);
247     break;
248
249     //unimplemented functions
250   case JTAG430_HALTCPU:  
251   case JTAG430_RELEASECPU:
252   case JTAG430_SETINSTRFETCH:
253
254   case JTAG430_ERASEFLASH:
255   case JTAG430_SETPC:
256     debugstr("This function is not yet implemented for MSP430X2.");
257     debughex(verb);
258     txdata(app,NOK,0);
259     break;
260   default:
261     (*(jtag_app.handle))(app,verb,len);
262   }
263   jtag430_resettap();
264 }
265