1 /*! \file jtagarm7tdmi.c
2 \brief ARM7TDMI JTAG (AT91R40008, AT91SAM7xxx)
8 #include "jtagarm7tdmi.h"
11 /**** 20-pin Connection Information (pin1 is on top-right for both connectors)****
12 GoodFET -> 7TDMI 20-pin connector (HE-10 connector)
19 9 4,6,8,10,12,14,16,18,20 (GND)
20 11 17/3 (nTRST) (different sources suggest 17 or 3 alternately)
21 ********************************/
23 /**** 14-pin Connection Information (pin1 is on top-right for both connectors)****
24 GoodFET -> 7TDMI 14-pin connector
34 http://hri.sourceforge.net/tools/jtag_faq_org.html
35 ********************************/
38 // ! Start JTAG, setup pins, reset TAP and return IDCODE
39 void jtagarm7tdmi_start() {
45 //! Reset TAP State Machine
48 /* WHAT SHOULD THIS MODULE DO?
54 * *scanchain1 (instr_primitive)
55 * *scanchain2 (hmmmm... perhaps we'll need to keep the debug calls)
65 retval = jtagtransn(ir, 4, LSB);
69 //! Connect the appropriate scan chain to TDO/TDI. SCAN_N, INTEST
70 unsigned long jtagarm7tdmi_scan(u8 chain, u8 testmode) { // PROVEN
72 When selecting a scan chain the “Run Test/Idle” state should never be reached, other-
73 wise, when in debug state, the core will not be correctly isolated and intrusive
74 commands occur. Therefore, it is recommended to pass directly from the “Update”
75 state” to the “Select DR” state each time the “Update” state is reached.
79 jtagtransn(ARM7TDMI_IR_SCAN_N, 4, LSB | NORETIDLE);
81 retval = jtagtransn(chain, 4, LSB | NORETIDLE);
83 jtagtransn(testmode, 4, LSB);
88 /************************* EmbeddedICE Primitives ****************************/
89 //! shifter for writing to chain2 (EmbeddedICE).
90 unsigned long eice_write(unsigned char reg, unsigned long data){
91 unsigned long retval, temp;
92 jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST);
94 retval = jtagtransn(data, 32, LSB| NOEND| NORETIDLE); // send in the data - 32-bits lsb
95 temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE); // send in the register address - 5 bits lsb
96 jtagtransn(1, 1, LSB); // send in the WRITE bit
100 //! shifter for reading from chain2 (EmbeddedICE).
101 unsigned long eice_read(unsigned char reg){ // PROVEN
102 unsigned long temp, retval;
103 jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST);
104 jtag_goto_shift_dr(); // send in the register address - 5 bits LSB
105 temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE);
106 jtagtransn(0L, 1, LSB); // clear TDI to select "read only"
107 jtag_goto_shift_dr(); // Now shift out the 32 bits
108 retval = jtagtransn(0L, 32, LSB); // atmel arm jtag docs pp.10-11: LSB first
113 //! push an instruction into the pipeline
114 unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){ // PROVEN
115 unsigned long retval;
116 jtagarm7tdmi_scan(1, ARM7TDMI_IR_INTEST);
118 jtag_goto_shift_dr();
119 // if the next instruction is to run using MCLK (master clock), set TDI
123 count_sysspd_instr_since_debug++;
128 count_dbgspd_instr_since_debug++;
132 // Now shift in the 32 bits
133 retval = jtagtransn(instr, 32, 0); // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock.
137 u32 jtagarm7tdmi_nop(u8 brkpt){
138 return jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, brkpt);
141 /******************** Complex Commands **************************/
143 //! Retrieve a 32-bit Register value
144 unsigned long jtagarm7tdmi_get_register(unsigned long reg) { //PROVEN
145 unsigned long retval=0L, instr;
146 if (eice_read(EICE_DBGSTATUS)& JTAG_ARM7TDMI_DBG_TBIT)
147 instr = THUMB_INSTR_STR_R0_r0 | reg | (reg<<16);
149 instr = (unsigned long)(reg<<12L) | (unsigned long)ARM_READ_REG; // STR Rx, [R14]
151 jtagarm7tdmi_nop( 0);
152 jtagarm7tdmi_nop( 0);
153 jtagarm7tdmi_instr_primitive(instr, 0);
154 jtagarm7tdmi_nop( 0);
155 jtagarm7tdmi_nop( 0);
156 jtagarm7tdmi_nop( 0);
157 retval = jtagarm7tdmi_nop( 0); // recover 32-bit word
161 //! Set a 32-bit Register value
162 void jtagarm7tdmi_set_register(unsigned long reg, unsigned long val) { // PROVEN (assuming target reg is word aligned)
164 //if (current_dbgstate & JTAG_ARM7TDMI_DBG_TBIT)
165 //instr = THUMB_WRITE_REG
166 instr = (unsigned long)(((unsigned long)reg<<12L) | ARM_WRITE_REG); // LDR Rx, [R14]
168 jtagarm7tdmi_nop( 0); // push nop into pipeline - clean out the pipeline...
169 jtagarm7tdmi_nop( 0); // push nop into pipeline - clean out the pipeline...
170 jtagarm7tdmi_instr_primitive(instr, 0); // push instr into pipeline - fetch
171 if (reg == ARM_REG_PC){
172 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
176 jtagarm7tdmi_nop( 0); // push nop into pipeline - decode
177 jtagarm7tdmi_nop( 0); // push nop into pipeline - execute
178 jtagarm7tdmi_instr_primitive(val, 0); // push 32-bit word on data bus
180 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
181 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
182 jtagarm7tdmi_nop( 0);
186 ///////////////////////////////////////////////////////////////////////////////////////////////////
187 //! Handles ARM7TDMI JTAG commands. Forwards others to JTAG.
188 void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len){
194 jtagarm7tdmi_start();
198 jtag_goto_shift_ir();
199 cmddataword[0] = jtagtransn(cmddata[0], 4, cmddata[1]);
204 jtag_goto_shift_dr();
205 cmddatalong[0] = jtagtransn(cmddatalong[1],cmddata[0],cmddata[1]);
208 case JTAGARM7_CHAIN0:
209 jtagarm7tdmi_scan(0, ARM7TDMI_IR_INTEST);
210 jtag_goto_shift_dr();
211 debughex32(cmddatalong[0]);
212 debughex(cmddataword[4]);
213 debughex32(cmddatalong[1]);
214 debughex32(cmddatalong[3]);
215 cmddatalong[0] = jtagtransn(cmddatalong[0], 32, LSB| NOEND| NORETIDLE);
216 cmddatalong[2] = jtagtransn(cmddataword[4], 9, MSB| NOEND| NORETIDLE);
217 cmddatalong[1] = jtagtransn(cmddatalong[1], 32, MSB| NOEND| NORETIDLE);
218 cmddatalong[3] = jtagtransn(cmddatalong[3], 32, MSB);
221 case JTAGARM7_SCANCHAIN1:
222 case JTAGARM7_DEBUG_INSTR:
223 cmddatalong[0] = jtagarm7tdmi_instr_primitive(cmddatalong[0],cmddata[4]);
226 case JTAGARM7_EICE_READ:
227 cmddatalong[0] = eice_read(cmddata[0]);
228 txdata(app,verb,0x4);
230 case JTAGARM7_EICE_WRITE:
231 eice_write(cmddata[4], cmddatalong[0]);
234 case JTAGARM7_GET_REGISTER:
236 cmddatalong[0] = jtagarm7tdmi_get_register(val);
239 case JTAGARM7_SET_REGISTER:
240 jtagarm7tdmi_set_register(cmddatalong[1], cmddatalong[0]);
245 //case JTAGARM7_STEP_INSTR:
246 /* case JTAGARM7_READ_CODE_MEMORY:
247 case JTAGARM7_WRITE_FLASH_PAGE:
248 case JTAGARM7_READ_FLASH_PAGE:
249 case JTAGARM7_MASS_ERASE_FLASH:
250 case JTAGARM7_PROGRAM_FLASH:
251 case JTAGARM7_LOCKCHIP:
252 case JTAGARM7_CHIP_ERASE:
255 jtaghandle(app,verb,len);