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)
62 u8 shift_ir(u8 ir, u8 flags){
65 retval = jtagtransn(ir, 4, LSB|flags);
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.
78 shift_ir(ARM7TDMI_IR_SCAN_N, NORETIDLE);
80 retval = jtagtransn(chain, 4, LSB | NORETIDLE);
81 shift_ir(testmode, NORETIDLE);
86 /************************* EmbeddedICE Primitives ****************************/
87 //! shifter for writing to chain2 (EmbeddedICE).
88 unsigned long eice_write(unsigned char reg, unsigned long data){
89 unsigned long retval, temp;
90 jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST);
92 retval = jtagtransn(data, 32, LSB| NOEND| NORETIDLE); // send in the data - 32-bits lsb
93 temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE); // send in the register address - 5 bits lsb
94 jtagtransn(1, 1, LSB); // send in the WRITE bit
98 //! shifter for reading from chain2 (EmbeddedICE).
99 unsigned long eice_read(unsigned char reg){ // PROVEN
100 unsigned long temp, retval;
101 jtagarm7tdmi_scan(2, ARM7TDMI_IR_INTEST);
102 jtag_goto_shift_dr(); // send in the register address - 5 bits LSB
103 temp = jtagtransn(reg, 5, LSB| NOEND| NORETIDLE);
104 jtagtransn(0L, 1, LSB); // clear TDI to select "read only"
105 jtag_goto_shift_dr(); // Now shift out the 32 bits
106 retval = jtagtransn(0L, 32, LSB); // atmel arm jtag docs pp.10-11: LSB first
111 //! push an instruction into the pipeline
112 unsigned long jtagarm7tdmi_instr_primitive(unsigned long instr, char breakpt){ // PROVEN
113 unsigned long retval;
114 jtagarm7tdmi_scan(1, ARM7TDMI_IR_INTEST);
116 jtag_goto_shift_dr();
117 // if the next instruction is to run using MCLK (master clock), set TDI
128 // Now shift in the 32 bits
129 retval = jtagtransn(instr, 32, 0); // Must return to RUN-TEST/IDLE state for instruction to enter pipeline, and causes debug clock.
133 u32 jtagarm7tdmi_nop(u8 brkpt){
134 return jtagarm7tdmi_instr_primitive(ARM_INSTR_NOP, brkpt);
137 /******************** Complex Commands **************************/
139 //! Retrieve a 32-bit Register value
140 unsigned long jtagarm7tdmi_get_register(unsigned long reg) { //PROVEN
141 unsigned long retval=0L, instr;
142 if (eice_read(EICE_DBGSTATUS)& JTAG_ARM7TDMI_DBG_TBIT)
143 instr = THUMB_INSTR_STR_R0_r0 | reg | (reg<<16);
145 instr = (unsigned long)(reg<<12L) | (unsigned long)ARM_READ_REG; // STR Rx, [R14]
147 jtagarm7tdmi_nop( 0);
148 jtagarm7tdmi_nop( 0);
149 jtagarm7tdmi_instr_primitive(instr, 0);
150 jtagarm7tdmi_nop( 0);
151 jtagarm7tdmi_nop( 0);
152 jtagarm7tdmi_nop( 0);
153 retval = jtagarm7tdmi_nop( 0); // recover 32-bit word
157 //! Set a 32-bit Register value
158 void jtagarm7tdmi_set_register(unsigned long reg, unsigned long val) { // PROVEN (assuming target reg is word aligned)
160 //if (current_dbgstate & JTAG_ARM7TDMI_DBG_TBIT)
161 //instr = THUMB_WRITE_REG
162 instr = (unsigned long)(((unsigned long)reg<<12L) | ARM_WRITE_REG); // LDR Rx, [R14]
164 jtagarm7tdmi_nop( 0); // push nop into pipeline - clean out the pipeline...
165 jtagarm7tdmi_nop( 0); // push nop into pipeline - clean out the pipeline...
166 jtagarm7tdmi_instr_primitive(instr, 0); // push instr into pipeline - fetch
167 if (reg == ARM_REG_PC){
168 jtagarm7tdmi_instr_primitive(val, 0); // push 32-bit word on data bus
169 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
170 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
172 jtagarm7tdmi_nop( 0); // push nop into pipeline - decode
173 jtagarm7tdmi_nop( 0); // push nop into pipeline - execute
174 jtagarm7tdmi_instr_primitive(val, 0); // push 32-bit word on data bus
176 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
177 jtagarm7tdmi_nop( 0); // push nop into pipeline - executed
178 jtagarm7tdmi_nop( 0);
182 ///////////////////////////////////////////////////////////////////////////////////////////////////
183 //! Handles ARM7TDMI JTAG commands. Forwards others to JTAG.
184 void jtagarm7tdmihandle(unsigned char app, unsigned char verb, unsigned long len){
190 jtagarm7tdmi_start();
194 cmddataword[0] = shift_ir(cmddata[0], cmddata[1]);
198 jtag_goto_shift_dr();
199 cmddatalong[0] = jtagtransn(cmddatalong[1],cmddata[0],cmddata[1]);
202 case JTAGARM7_CHAIN0:
203 jtagarm7tdmi_scan(0, ARM7TDMI_IR_INTEST);
204 jtag_goto_shift_dr();
205 //debughex32(cmddatalong[0]);
206 //debughex(cmddataword[4]);
207 //debughex32(cmddatalong[1]);
208 //debughex32(cmddatalong[3]);
209 cmddatalong[0] = jtagtransn(cmddatalong[0], 32, LSB| NOEND| NORETIDLE);
210 cmddatalong[2] = jtagtransn(cmddataword[4], 9, MSB| NOEND| NORETIDLE);
211 cmddatalong[1] = jtagtransn(cmddatalong[1], 32, MSB| NOEND| NORETIDLE);
212 cmddatalong[3] = jtagtransn(cmddatalong[3], 32, MSB);
215 case JTAGARM7_SCANCHAIN1:
216 case JTAGARM7_DEBUG_INSTR:
217 cmddatalong[0] = jtagarm7tdmi_instr_primitive(cmddatalong[0],cmddata[4]);
220 case JTAGARM7_EICE_READ:
221 cmddatalong[0] = eice_read(cmddata[0]);
222 txdata(app,verb,0x4);
224 case JTAGARM7_EICE_WRITE:
225 eice_write(cmddata[4], cmddatalong[0]);
228 case JTAGARM7_GET_REGISTER:
230 cmddatalong[0] = jtagarm7tdmi_get_register(val);
233 case JTAGARM7_SET_REGISTER:
234 jtagarm7tdmi_set_register(cmddatalong[1], cmddatalong[0]);
239 //case JTAGARM7_STEP_INSTR:
240 /* case JTAGARM7_READ_CODE_MEMORY:
241 case JTAGARM7_WRITE_FLASH_PAGE:
242 case JTAGARM7_READ_FLASH_PAGE:
243 case JTAGARM7_MASS_ERASE_FLASH:
244 case JTAGARM7_PROGRAM_FLASH:
245 case JTAGARM7_LOCKCHIP:
246 case JTAGARM7_CHIP_ERASE:
249 jtaghandle(app,verb,len);