1 /******************************************************************************
2 * @file JTAG_DP.c
3 * @brief CMSIS-DAP JTAG DP I/O
4 * @version V1.10
5 * @date 20. May 2015
6 *
7 * @note
8 * Copyright (C) 2012-2015 ARM Limited. All rights reserved.
9 *
10 * @par
11 * ARM Limited (ARM) is supplying this software for use with Cortex-M
12 * processor based microcontrollers.
13 *
14 * @par
15 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
16 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
18 * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
19 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
20 *
21 ******************************************************************************/
22
23 #include "DAP_config.h"
24 #include "DAP.h"
25
26
27 // JTAG Macros
28
29 #define PIN_TCK_SET PIN_SWCLK_TCK_SET
30 #define PIN_TCK_CLR PIN_SWCLK_TCK_CLR
31 #define PIN_TMS_SET PIN_SWDIO_TMS_SET
32 #define PIN_TMS_CLR PIN_SWDIO_TMS_CLR
33
34 #define JTAG_CYCLE_TCK() \
35 PIN_TCK_CLR(); \
36 PIN_DELAY(); \
37 PIN_TCK_SET(); \
38 PIN_DELAY()
39
40 #define JTAG_CYCLE_TDI(tdi) \
41 PIN_TDI_OUT(tdi); \
42 PIN_TCK_CLR(); \
43 PIN_DELAY(); \
44 PIN_TCK_SET(); \
45 PIN_DELAY()
46
47 #define JTAG_CYCLE_TDO(tdo) \
48 PIN_TCK_CLR(); \
49 PIN_DELAY(); \
50 tdo = PIN_TDO_IN(); \
51 PIN_TCK_SET(); \
52 PIN_DELAY()
53
54 #define JTAG_CYCLE_TDIO(tdi,tdo) \
55 PIN_TDI_OUT(tdi); \
56 PIN_TCK_CLR(); \
57 PIN_DELAY(); \
58 tdo = PIN_TDO_IN(); \
59 PIN_TCK_SET(); \
60 PIN_DELAY()
61
62 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
63
64
65 #if (DAP_JTAG != 0)
66
67
68 // Generate JTAG Sequence
69 // info: sequence information
70 // tdi: pointer to TDI generated data
71 // tdo: pointer to TDO captured data
72 // return: none
JTAG_Sequence(uint32_t info,const uint8_t * tdi,uint8_t * tdo)73 void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo) {
74 uint32_t i_val;
75 uint32_t o_val;
76 uint32_t bit;
77 uint32_t n, k;
78
79 n = info & JTAG_SEQUENCE_TCK;
80 if (n == 0U) { n = 64U; }
81
82 if (info & JTAG_SEQUENCE_TMS) {
83 PIN_TMS_SET();
84 } else {
85 PIN_TMS_CLR();
86 }
87
88 while (n) {
89 i_val = *tdi++;
90 o_val = 0U;
91 for (k = 8U; k && n; k--, n--) {
92 JTAG_CYCLE_TDIO(i_val, bit);
93 i_val >>= 1;
94 o_val >>= 1;
95 o_val |= bit << 7;
96 }
97 o_val >>= k;
98 if (info & JTAG_SEQUENCE_TDO) {
99 *tdo++ = (uint8_t)o_val;
100 }
101 }
102 }
103
104
105 // JTAG Set IR
106 // ir: IR value
107 // return: none
108 #define JTAG_IR_Function(speed) /**/ \
109 void JTAG_IR_##speed (uint32_t ir) { \
110 uint32_t n; \
111 \
112 PIN_TMS_SET(); \
113 JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
114 JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \
115 PIN_TMS_CLR(); \
116 JTAG_CYCLE_TCK(); /* Capture-IR */ \
117 JTAG_CYCLE_TCK(); /* Shift-IR */ \
118 \
119 PIN_TDI_OUT(1U); \
120 for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \
121 JTAG_CYCLE_TCK(); /* Bypass before data */ \
122 } \
123 for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1U; n; n--) { \
124 JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \
125 ir >>= 1; \
126 } \
127 n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \
128 if (n) { \
129 JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \
130 PIN_TDI_OUT(1U); \
131 for (--n; n; n--) { \
132 JTAG_CYCLE_TCK(); /* Bypass after data */ \
133 } \
134 PIN_TMS_SET(); \
135 JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \
136 } else { \
137 PIN_TMS_SET(); \
138 JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \
139 } \
140 \
141 JTAG_CYCLE_TCK(); /* Update-IR */ \
142 PIN_TMS_CLR(); \
143 JTAG_CYCLE_TCK(); /* Idle */ \
144 PIN_TDI_OUT(1U); \
145 }
146
147
148 // JTAG Transfer I/O
149 // request: A[3:2] RnW APnDP
150 // data: DATA[31:0]
151 // return: ACK[2:0]
152 #define JTAG_TransferFunction(speed) /**/ \
153 uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) { \
154 uint32_t ack; \
155 uint32_t bit; \
156 uint32_t val; \
157 uint32_t n; \
158 \
159 PIN_TMS_SET(); \
160 JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
161 PIN_TMS_CLR(); \
162 JTAG_CYCLE_TCK(); /* Capture-DR */ \
163 JTAG_CYCLE_TCK(); /* Shift-DR */ \
164 \
165 for (n = DAP_Data.jtag_dev.index; n; n--) { \
166 JTAG_CYCLE_TCK(); /* Bypass before data */ \
167 } \
168 \
169 JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \
170 ack = bit << 1; \
171 JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \
172 ack |= bit << 0; \
173 JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \
174 ack |= bit << 2; \
175 \
176 if (ack != DAP_TRANSFER_OK) { \
177 /* Exit on error */ \
178 PIN_TMS_SET(); \
179 JTAG_CYCLE_TCK(); /* Exit1-DR */ \
180 goto exit; \
181 } \
182 \
183 if (request & DAP_TRANSFER_RnW) { \
184 /* Read Transfer */ \
185 val = 0U; \
186 for (n = 31U; n; n--) { \
187 JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \
188 val |= bit << 31; \
189 val >>= 1; \
190 } \
191 n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \
192 if (n) { \
193 JTAG_CYCLE_TDO(bit); /* Get D31 */ \
194 for (--n; n; n--) { \
195 JTAG_CYCLE_TCK(); /* Bypass after data */ \
196 } \
197 PIN_TMS_SET(); \
198 JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
199 } else { \
200 PIN_TMS_SET(); \
201 JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \
202 } \
203 val |= bit << 31; \
204 if (data) { *data = val; } \
205 } else { \
206 /* Write Transfer */ \
207 val = *data; \
208 for (n = 31U; n; n--) { \
209 JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \
210 val >>= 1; \
211 } \
212 n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1u; \
213 if (n) { \
214 JTAG_CYCLE_TDI(val); /* Set D31 */ \
215 for (--n; n; n--) { \
216 JTAG_CYCLE_TCK(); /* Bypass after data */ \
217 } \
218 PIN_TMS_SET(); \
219 JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
220 } else { \
221 PIN_TMS_SET(); \
222 JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \
223 } \
224 } \
225 \
226 exit: \
227 JTAG_CYCLE_TCK(); /* Update-DR */ \
228 PIN_TMS_CLR(); \
229 JTAG_CYCLE_TCK(); /* Idle */ \
230 PIN_TDI_OUT(1U); \
231 \
232 /* Idle cycles */ \
233 n = DAP_Data.transfer.idle_cycles; \
234 while (n--) { \
235 JTAG_CYCLE_TCK(); /* Idle */ \
236 } \
237 \
238 return ((uint8_t)ack); \
239 }
240
241
242 #undef PIN_DELAY
243 #define PIN_DELAY() PIN_DELAY_FAST()
244 JTAG_IR_Function(Fast);
245 JTAG_TransferFunction(Fast);
246
247 #undef PIN_DELAY
248 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
249 JTAG_IR_Function(Slow);
250 JTAG_TransferFunction(Slow);
251
252
253 // JTAG Read IDCODE register
254 // return: value read
JTAG_ReadIDCode(void)255 uint32_t JTAG_ReadIDCode (void) {
256 uint32_t bit;
257 uint32_t val;
258 uint32_t n;
259
260 PIN_TMS_SET();
261 JTAG_CYCLE_TCK(); /* Select-DR-Scan */
262 PIN_TMS_CLR();
263 JTAG_CYCLE_TCK(); /* Capture-DR */
264 JTAG_CYCLE_TCK(); /* Shift-DR */
265
266 for (n = DAP_Data.jtag_dev.index; n; n--) {
267 JTAG_CYCLE_TCK(); /* Bypass before data */
268 }
269
270 val = 0U;
271 for (n = 31U; n; n--) {
272 JTAG_CYCLE_TDO(bit); /* Get D0..D30 */
273 val |= bit << 31;
274 val >>= 1;
275 }
276 PIN_TMS_SET();
277 JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */
278 val |= bit << 31;
279
280 JTAG_CYCLE_TCK(); /* Update-DR */
281 PIN_TMS_CLR();
282 JTAG_CYCLE_TCK(); /* Idle */
283
284 return (val);
285 }
286
287
288 // JTAG Write ABORT register
289 // data: value to write
290 // return: none
JTAG_WriteAbort(uint32_t data)291 void JTAG_WriteAbort (uint32_t data) {
292 uint32_t n;
293
294 PIN_TMS_SET();
295 JTAG_CYCLE_TCK(); /* Select-DR-Scan */
296 PIN_TMS_CLR();
297 JTAG_CYCLE_TCK(); /* Capture-DR */
298 JTAG_CYCLE_TCK(); /* Shift-DR */
299
300 for (n = DAP_Data.jtag_dev.index; n; n--) {
301 JTAG_CYCLE_TCK(); /* Bypass before data */
302 }
303
304 PIN_TDI_OUT(0U);
305 JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */
306 JTAG_CYCLE_TCK(); /* Set A2=0 */
307 JTAG_CYCLE_TCK(); /* Set A3=0 */
308
309 for (n = 31U; n; n--) {
310 JTAG_CYCLE_TDI(data); /* Set D0..D30 */
311 data >>= 1;
312 }
313 n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1u;
314 if (n) {
315 JTAG_CYCLE_TDI(data); /* Set D31 */
316 for (--n; n; n--) {
317 JTAG_CYCLE_TCK(); /* Bypass after data */
318 }
319 PIN_TMS_SET();
320 JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */
321 } else {
322 PIN_TMS_SET();
323 JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */
324 }
325
326 JTAG_CYCLE_TCK(); /* Update-DR */
327 PIN_TMS_CLR();
328 JTAG_CYCLE_TCK(); /* Idle */
329 PIN_TDI_OUT(1U);
330 }
331
332
333 // JTAG Set IR
334 // ir: IR value
335 // return: none
JTAG_IR(uint32_t ir)336 void JTAG_IR (uint32_t ir) {
337 if (DAP_Data.fast_clock) {
338 JTAG_IR_Fast(ir);
339 } else {
340 JTAG_IR_Slow(ir);
341 }
342 }
343
344
345 // JTAG Transfer I/O
346 // request: A[3:2] RnW APnDP
347 // data: DATA[31:0]
348 // return: ACK[2:0]
JTAG_Transfer(uint32_t request,uint32_t * data)349 uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) {
350 if (DAP_Data.fast_clock) {
351 return JTAG_TransferFast(request, data);
352 } else {
353 return JTAG_TransferSlow(request, data);
354 }
355 }
356
357
358 #endif /* (DAP_JTAG != 0) */
359