Reading seems to work on MSP430X2, but some regions seem to be unpopulated.
[goodfet] / firmware / apps / jtag / jtag430x2.c
1 /*! \file jtag430x2.c
2   \author Travis Goodspeed <travis at radiantmachines.com>
3   
4   This is an implementation of the MSP430X2 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 unsigned char jtagid;
15
16 //! Get the JTAG ID
17 unsigned char jtag430x2_jtagid(){
18   jtag430_resettap();
19   return jtagid=jtag_ir_shift8(IR_BYPASS);
20 }
21 //! Start JTAG, take pins
22 unsigned char jtag430x2_start(){
23   jtagsetup();
24   
25   //Known-good starting position.
26   //Might be unnecessary.
27   SETTST;
28   SETRST;
29   
30   delay(0xFFFF);
31   
32   //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 JTAG
33   CLRRST;
34   delay(10);
35   CLRTST;
36
37   delay(5);
38   SETTST;
39   msdelay(5);
40   SETRST;
41   P5DIR&=~RST;
42   
43   delay(0xFFFF);
44   
45   //Perform a reset and disable watchdog.
46   return jtag430x2_jtagid();
47 }
48
49 unsigned int jtag430_coreid(){
50   jtag_ir_shift8(IR_COREIP_ID);
51   return jtag_dr_shift16(0);
52 }
53
54 unsigned long jtag430_deviceid(){
55   jtag_ir_shift8(IR_DEVICE_ID);
56   return jtag_dr_shift20(0);
57 }
58
59
60 //! Write data to address
61 unsigned int jtag430x2_writemem(unsigned long adr,
62                                 unsigned long data){
63   jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
64   if(jtag_ir_shift8(0) & 0x0301){
65     CLRTCLK;
66     jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
67     if(adr>=0x100)
68       jtag_ir_shift8(0x0500);//word mode
69     else
70       jtag_ir_shift8(0x0510);//byte mode
71     jtag_ir_shift8(IR_ADDR_16BIT);
72     jtag_dr_shift20(adr);
73     
74     SETTCLK;
75     
76     jtag_ir_shift8(IR_DATA_TO_ADDR);
77     jtag_ir_shift8(data);//16 word
78
79     CLRTCLK;
80     jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
81     jtag_ir_shift8(0x0501);
82     SETTCLK;
83
84     CLRTCLK;
85     SETTCLK;
86     //init state
87   }else{
88     while(1) P1OUT^=1; //loop if locked up
89   }
90 }
91
92 //! Read data from address
93 unsigned int jtag430x2_readmem(unsigned long adr){
94   unsigned int toret=0;
95
96   jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
97   if(jtag_dr_shift16(0) & 0x0301){
98     // Read Memory                                                                                                                                                                 
99     CLRTCLK;
100     jtag_ir_shift8(IR_CNTRL_SIG_16BIT);
101     if(adr>=0x100){
102       jtag_dr_shift16(0x0501);//word read
103     }else{
104       jtag_dr_shift16(0x0511);//byte read
105     }
106     jtag_ir_shift8(IR_ADDR_16BIT);
107     jtag_dr_shift20(adr); //20
108
109     jtag_ir_shift8(IR_DATA_TO_ADDR);
110     SETTCLK;
111     CLRTCLK;
112     toret = jtag_dr_shift16(0x0000);
113     
114     SETTCLK;
115     // one or more cycle, so CPU is driving correct MAB
116
117     CLRTCLK;
118     SETTCLK;
119     // Processor is now again in Init State
120   }else{
121     return 0xDEAD;
122   }
123   
124   return toret;
125 }
126
127
128 //! Handles classic MSP430 JTAG commands.  Forwards others to JTAG.
129 void jtag430x2handle(unsigned char app,
130                    unsigned char verb,
131                    unsigned char len){
132   jtag430_resettap();
133   switch(verb){
134   case START:
135     //Enter JTAG mode.
136     do cmddata[0]=jtag430x2_start();
137     while(cmddata[0]==00 || cmddata[0]==0xFF);
138     
139     //MSP430 or MSP430X
140     if(jtagid==MSP430JTAGID){ 
141       jtag430mode=MSP430MODE;
142       drwidth=16;
143     }else if(jtagid==MSP430X2JTAGID){
144       jtag430mode=MSP430X2MODE;
145       drwidth=20;
146     }else{
147       txdata(app,NOK,1);
148       return;
149     }
150     
151     //TAP setup, fuse check
152     //jtag430_resettap();
153     txdata(app,verb,1);
154     break;
155   case JTAG430_READMEM:
156   case PEEK:
157     cmddataword[0]=jtag430x2_readmem(cmddataword[0]);
158     //cmddataword[0]=jtag430_readmem(cmddataword[0]);
159     txdata(app,verb,2);
160     break;
161   case JTAG430_COREIP_ID:
162     cmddataword[0]=jtag430_coreid();
163     txdata(app,verb,2);
164     break;
165   case JTAG430_DEVICE_ID:
166     cmddatalong[0]=jtag430_deviceid();
167     txdata(app,verb,4);
168     break;
169   case JTAG430_HALTCPU:
170   case JTAG430_RELEASECPU:
171   case JTAG430_SETINSTRFETCH:
172   case JTAG430_WRITEMEM:
173   case POKE:
174     jtag430x2_writemem(cmddataword[0],
175                        cmddataword[1]);
176     cmddataword[0]=jtag430x2_readmem(cmddataword[0]);
177     txdata(app,verb,2);
178     break;
179   case JTAG430_WRITEFLASH:
180   case JTAG430_ERASEFLASH:
181   case JTAG430_SETPC:
182   default:
183     jtaghandle(app,verb,len);
184   }
185   jtag430_resettap();
186 }