MSP430 JTAG works.
[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
83 //! Write data to address.
84 void jtag430_writeflash(unsigned int adr, unsigned int data){
85   //TODO; this is complicated.
86 }
87
88
89 //! Reset the TAP state machine.
90 void jtag430_resettap(){
91   int i;
92   // Settle output
93   SETTMS;
94   SETTDI;
95   SETTCK;
96
97   // Navigate to reset state.
98   // Should be at least six.
99   for(i=0;i<4;i++){
100     CLRTCK;
101     SETTCK;
102   }
103
104   // test-logic-reset
105   CLRTCK;
106   CLRTMS;
107   SETTCK;
108   SETTMS;
109   // idle
110
111     
112   /* sacred, by spec.
113      Sometimes this isn't necessary. */
114   // fuse check
115   CLRTMS;
116   delay(50);
117   SETTMS;
118   CLRTMS;
119   delay(50);
120   SETTMS;
121   /**/
122   
123 }
124
125 //! Start JTAG, take pins
126 void jtag430_start(){
127   jtagsetup();
128   
129   //Known-good starting position.
130   //Might be unnecessary.
131   SETTST;
132   SETRST;
133   delay(0xFFFF);
134   
135   //Entry sequence from Page 67 of SLAU265A for 4-wire MSP430 JTAG
136   CLRRST;
137   delay(100);
138   CLRTST;
139   delay(50);
140   SETTST;
141   delay(50);
142   SETRST;
143   P5DIR&=~RST;
144   delay(0xFFFF);
145 }
146
147 //! Set CPU to Instruction Fetch
148 void jtag430_setinstrfetch(){
149   jtag_ir_shift8(IR_CNTRL_SIG_CAPTURE);
150
151   // Wait until instruction fetch state.
152   while(1){
153     if (jtag_dr_shift16(0x0000) & 0x0080)
154       return;
155     CLRTCLK;
156     SETTCLK;
157   }
158 }
159
160 //! Handles unique MSP430 JTAG commands.  Forwards others to JTAG.
161 void jtag430handle(unsigned char app,
162                    unsigned char verb,
163                    unsigned char len){
164   unsigned char i;
165   switch(verb){
166   case START:
167     //Enter JTAG mode.
168     jtag430_start();
169     //TAP setup, fuse check
170     jtag430_resettap();
171     txdata(app,verb,0);
172     break;
173   case JTAG430_HALTCPU:
174     jtag430_haltcpu();
175     txdata(app,verb,0);
176     break;
177   case JTAG430_RELEASECPU:
178     jtag430_releasecpu();
179     txdata(app,verb,0);
180     break;
181   case JTAG430_SETINSTRFETCH:
182     jtag430_setinstrfetch();
183     txdata(app,verb,0);
184     break;
185
186     
187   case JTAG430_READMEM:
188   case PEEK:
189     cmddataword[0]=jtag430_readmem(cmddataword[0]);
190     txdata(app,verb,2);
191     break;
192   case JTAG430_WRITEMEM:
193   case POKE:
194     jtag430_writemem(cmddataword[0],cmddataword[1]);
195     txdata(app,verb,0);
196     break;
197   case JTAG430_WRITEFLASH:
198     jtag430_writeflash(cmddataword[0],cmddataword[1]);
199     txdata(app,verb,0);
200     break;
201   case JTAG430_SETPC:
202     jtag430_setpc(cmddataword[0]);
203     txdata(app,verb,0);
204     break;
205   default:
206     jtaghandle(app,verb,len);
207   }
208 }
209