2 \brief ARM7TDMI JTAG (AT91R40008, AT91SAM7xxx)
10 /**** 20-pin Connection Information (pin1 is on top-right for both connectors)****
11 GoodFET -> 7TDMI 20-pin connector (HE-10 connector)
18 9 4,6,8,10,12,14,16,18,20 (GND)
19 11 17/3 (nTRST) (different sources suggest 17 or 3 alternately)
20 ********************************/
22 /**** 14-pin Connection Information (pin1 is on top-right for both connectors)****
23 GoodFET -> 7TDMI 14-pin connector
33 http://hri.sourceforge.net/tools/jtag_faq_org.html
34 ********************************/
36 /* WHAT SHOULD THIS MODULE DO?
42 * *scanchain1 (instr_primitive)
43 * *scanchain2 (hmmmm... perhaps we'll need to keep the debug calls)
50 // ! Start JTAG, setup pins, reset TAP and return IDCODE
51 void jtagarm7tdmi_start() {
58 u8 shift_ir(u8 ir, u8 flags){
61 retval = jtagtransn(ir, 4, LSB|flags);
65 //! Connect the appropriate scan chain to TDO/TDI. SCAN_N, INTEST
66 unsigned long jtagarm7tdmi_scan(u8 chain, u8 testmode) { // PROVEN
68 When selecting a scan chain the “Run Test/Idle” state should never be reached, other-
69 wise, when in debug state, the core will not be correctly isolated and intrusive
70 commands occur. Therefore, it is recommended to pass directly from the “Update”
71 state” to the “Select DR” state each time the “Update” state is reached.
74 shift_ir(ARM7TDMI_IR_SCAN_N, NORETIDLE);
76 retval = jtagtransn(chain, 4, LSB | NORETIDLE);
77 shift_ir(testmode, NORETIDLE);
82 /************************* EmbeddedICE Primitives ****************************/
83 //! shifter for writing to chain2 (EmbeddedICE).
84 unsigned long eice_write(unsigned char reg, unsigned long data){
85 unsigned long retval, temp;
86 jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST);
88 retval = jtagtransn(data, 32, LSB| NOEND| NORETIDLE); // send in the data - 32-bits lsb
89 temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE); // send in the register address - 5 bits lsb
90 jtagtransn(1, 1, LSB); // send in the WRITE bit
94 //! shifter for reading from chain2 (EmbeddedICE).
95 unsigned long eice_read(unsigned char reg){ // PROVEN
96 unsigned long temp, retval;
97 jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST);
98 jtag_goto_shift_dr(); // send in the register address - 5 bits LSB
99 temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE);
100 jtagtransn(0L, 1, LSB); // clear TDI to select "read only"
101 jtag_goto_shift_dr(); // Now shift out the 32 bits
102 retval = jtagtransn(0L, 32, LSB); // atmel arm jtag docs pp.10-11: LSB first
107 //! push an instruction into the pipeline
108 unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){ // PROVEN
109 unsigned long retval;
110 jtagarm7tdmi_scan(1, ARM7TDMI_IR_INTEST);
112 jtag_goto_shift_dr();
113 // if the next instruction is to run using MCLK (master clock), set TDI
124 // Now shift in the 32 bits
125 retval = jtagtransn(instr, 32, 0); // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock.
129 u32 jtagarm7tdmi_nop(u8 brkpt){
130 return jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, brkpt);
133 /******************** Complex Commands **************************/
135 //! Retrieve a 32-bit Register value
136 unsigned long jtagarm7tdmi_get_register(unsigned long reg) { //PROVEN
137 unsigned long retval=0L, instr;
138 if (eice_read(EICE_DBGSTATUS)& JTAG_ARM7TDMI_DBG_TBIT)
139 instr = THUMB_READ_REG | reg | (reg<<16);
141 instr = (unsigned long)(reg<<12L) | (unsigned long)ARM_READ_REG; // STR Rx, [R14]
143 jtagarm7tdmi_nop( 0);
144 jtagarm7tdmi_nop( 0);
145 jtagarm7tdmi_instr_primitive(instr, 0);
146 jtagarm7tdmi_nop( 0);
147 jtagarm7tdmi_nop( 0);
148 jtagarm7tdmi_nop( 0);
149 retval = jtagarm7tdmi_nop( 0); // recover 32-bit word
153 //! Set a 32-bit Register value
154 void jtagarm7tdmi_set_register(unsigned long reg, unsigned long val) { // PROVEN (assuming target reg is word aligned)
156 if (eice_read(EICE_DBGSTATUS) & JTAG_ARM7TDMI_DBG_TBIT)
157 instr = THUMB_WRITE_REG | (reg&7) | ((reg&7)<<16);
159 instr = (unsigned long)(((unsigned long)reg<<12L) | ARM_WRITE_REG); // LDR Rx, [R14]
161 jtagarm7tdmi_nop( 0); // push nop into pipeline - clean out the pipeline...
162 jtagarm7tdmi_nop( 0); // push nop into pipeline - clean out the pipeline...
163 jtagarm7tdmi_instr_primitive(instr, 0); // push instr into pipeline - fetch
164 if (reg == ARM_REG_PC){
165 jtagarm7tdmi_instr_primitive(val, 0); // push 32-bit word on data bus
166 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
167 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
169 jtagarm7tdmi_nop( 0); // push nop into pipeline - decode
170 jtagarm7tdmi_nop( 0); // push nop into pipeline - execute
171 jtagarm7tdmi_instr_primitive(val, 0); // push 32-bit word on data bus
173 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
174 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
175 jtagarm7tdmi_nop( 0);
179 ///////////////////////////////////////////////////////////////////////////////////////////////////
180 //! Handles ARM7TDMI JTAG commands. Forwards others to JTAG.
181 void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len){
187 jtagarm7tdmi_start();
191 cmddataword[0] = shift_ir(cmddata[0], cmddata[1]);
195 jtag_goto_shift_dr();
196 cmddatalong[0] = jtagtransn(cmddatalong[1],cmddata[0],cmddata[1]);
199 case JTAGARM7_CHAIN0:
200 jtagarm7tdmi_scan(0, ARM7TDMI_IR_INTEST);
201 jtag_goto_shift_dr();
202 //debughex32(cmddatalong[0]);
203 //debughex(cmddataword[4]);
204 //debughex32(cmddatalong[1]);
205 //debughex32(cmddatalong[3]);
206 cmddatalong[0] = jtagtransn(cmddatalong[0], 32, LSB| NOEND| NORETIDLE);
207 cmddatalong[2] = jtagtransn(cmddataword[4], 9, MSB| NOEND| NORETIDLE);
208 cmddatalong[1] = jtagtransn(cmddatalong[1], 32, MSB| NOEND| NORETIDLE);
209 cmddatalong[3] = jtagtransn(cmddatalong[3], 32, MSB);
212 case JTAGARM7_SCANCHAIN1:
213 case JTAGARM7_DEBUG_INSTR:
214 cmddatalong[0] = jtagarm7tdmi_instr_primitive(cmddatalong[0],cmddata[4]);
217 case JTAGARM7_EICE_READ:
218 cmddatalong[0] = eice_read(cmddata[0]);
219 txdata(app,verb,0x4);
221 case JTAGARM7_EICE_WRITE:
222 eice_write(cmddata[4], cmddatalong[0]);
225 case JTAGARM7_GET_REGISTER:
227 cmddatalong[0] = jtagarm7tdmi_get_register(val);
230 case JTAGARM7_SET_REGISTER:
231 jtagarm7tdmi_set_register(cmddatalong[1], cmddatalong[0]);
234 case JTAG_RESETTARGET:
241 //case JTAGARM7_STEP_INSTR:
242 /* case JTAGARM7_READ_CODE_MEMORY:
243 case JTAGARM7_WRITE_FLASH_PAGE:
244 case JTAGARM7_READ_FLASH_PAGE:
245 case JTAGARM7_MASS_ERASE_FLASH:
246 case JTAGARM7_PROGRAM_FLASH:
247 case JTAGARM7_LOCKCHIP:
248 case JTAGARM7_CHIP_ERASE:
251 jtaghandle(app,verb,len);