1 /******************************************************************************
\r
3 * @brief CMSIS-DAP JTAG DP I/O
\r
8 * Copyright (C) 2012 ARM Limited. All rights reserved.
\r
11 * ARM Limited (ARM) is supplying this software for use with Cortex-M
\r
12 * processor based microcontrollers.
\r
15 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
\r
16 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
\r
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
\r
18 * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
\r
19 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
\r
21 ******************************************************************************/
\r
23 #include "DAP_config.h"
\r
29 #define PIN_TCK_SET PIN_SWCLK_TCK_SET
\r
30 #define PIN_TCK_CLR PIN_SWCLK_TCK_CLR
\r
31 #define PIN_TMS_SET PIN_SWDIO_TMS_SET
\r
32 #define PIN_TMS_CLR PIN_SWDIO_TMS_CLR
\r
34 #define JTAG_CYCLE_TCK() \
\r
40 #define JTAG_CYCLE_TDI(tdi) \
\r
47 #define JTAG_CYCLE_TDO(tdo) \
\r
50 tdo = PIN_TDO_IN(); \
\r
54 #define JTAG_CYCLE_TDIO(tdi,tdo) \
\r
58 tdo = PIN_TDO_IN(); \
\r
62 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
\r
68 // Generate JTAG Sequence
\r
69 // info: sequence information
\r
70 // tdi: pointer to TDI generated data
\r
71 // tdo: pointer to TDO captured data
\r
73 void JTAG_Sequence (uint32_t info, uint8_t *tdi, uint8_t *tdo) {
\r
79 n = info & JTAG_SEQUENCE_TCK;
\r
82 if (info & JTAG_SEQUENCE_TMS) {
\r
91 for (k = 8; k && n; k--, n--) {
\r
92 JTAG_CYCLE_TDIO(i_val, bit);
\r
98 if (info & JTAG_SEQUENCE_TDO) {
\r
108 #define JTAG_IR_Function(speed) /**/ \
\r
109 void JTAG_IR_##speed (uint32_t ir) { \
\r
113 JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
\r
114 JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \
\r
116 JTAG_CYCLE_TCK(); /* Capture-IR */ \
\r
117 JTAG_CYCLE_TCK(); /* Shift-IR */ \
\r
120 for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \
\r
121 JTAG_CYCLE_TCK(); /* Bypass before data */ \
\r
123 for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1; n; n--) { \
\r
124 JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \
\r
127 n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \
\r
129 JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \
\r
131 for (--n; n; n--) { \
\r
132 JTAG_CYCLE_TCK(); /* Bypass after data */ \
\r
135 JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \
\r
138 JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \
\r
141 JTAG_CYCLE_TCK(); /* Update-IR */ \
\r
143 JTAG_CYCLE_TCK(); /* Idle */ \
\r
148 // JTAG Transfer I/O
\r
149 // request: A[3:2] RnW APnDP
\r
150 // data: DATA[31:0]
\r
151 // return: ACK[2:0]
\r
152 #define JTAG_TransferFunction(speed) /**/ \
\r
153 uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) { \
\r
160 JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
\r
162 JTAG_CYCLE_TCK(); /* Capture-DR */ \
\r
163 JTAG_CYCLE_TCK(); /* Shift-DR */ \
\r
165 for (n = DAP_Data.jtag_dev.index; n; n--) { \
\r
166 JTAG_CYCLE_TCK(); /* Bypass before data */ \
\r
169 JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \
\r
171 JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \
\r
173 JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \
\r
176 if (ack != DAP_TRANSFER_OK) { \
\r
177 /* Exit on error */ \
\r
179 JTAG_CYCLE_TCK(); /* Exit1-DR */ \
\r
183 if (request & DAP_TRANSFER_RnW) { \
\r
184 /* Read Transfer */ \
\r
186 for (n = 31; n; n--) { \
\r
187 JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \
\r
188 val |= bit << 31; \
\r
191 n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1; \
\r
193 JTAG_CYCLE_TDO(bit); /* Get D31 */ \
\r
194 for (--n; n; n--) { \
\r
195 JTAG_CYCLE_TCK(); /* Bypass after data */ \
\r
198 JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
\r
201 JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \
\r
203 val |= bit << 31; \
\r
204 if (data) *data = val; \
\r
206 /* Write Transfer */ \
\r
208 for (n = 31; n; n--) { \
\r
209 JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \
\r
212 n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1; \
\r
214 JTAG_CYCLE_TDI(val); /* Set D31 */ \
\r
215 for (--n; n; n--) { \
\r
216 JTAG_CYCLE_TCK(); /* Bypass after data */ \
\r
219 JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
\r
222 JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \
\r
227 JTAG_CYCLE_TCK(); /* Update-DR */ \
\r
229 JTAG_CYCLE_TCK(); /* Idle */ \
\r
232 /* Idle cycles */ \
\r
233 n = DAP_Data.transfer.idle_cycles; \
\r
235 JTAG_CYCLE_TCK(); /* Idle */ \
\r
243 #define PIN_DELAY() PIN_DELAY_FAST()
\r
244 JTAG_IR_Function(Fast);
\r
245 JTAG_TransferFunction(Fast);
\r
248 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
\r
249 JTAG_IR_Function(Slow);
\r
250 JTAG_TransferFunction(Slow);
\r
253 // JTAG Read IDCODE register
\r
254 // return: value read
\r
255 uint32_t JTAG_ReadIDCode (void) {
\r
261 JTAG_CYCLE_TCK(); /* Select-DR-Scan */
\r
263 JTAG_CYCLE_TCK(); /* Capture-DR */
\r
264 JTAG_CYCLE_TCK(); /* Shift-DR */
\r
266 for (n = DAP_Data.jtag_dev.index; n; n--) {
\r
267 JTAG_CYCLE_TCK(); /* Bypass before data */
\r
271 for (n = 31; n; n--) {
\r
272 JTAG_CYCLE_TDO(bit); /* Get D0..D30 */
\r
277 JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */
\r
280 JTAG_CYCLE_TCK(); /* Update-DR */
\r
282 JTAG_CYCLE_TCK(); /* Idle */
\r
288 // JTAG Write ABORT register
\r
289 // data: value to write
\r
291 void JTAG_WriteAbort (uint32_t data) {
\r
295 JTAG_CYCLE_TCK(); /* Select-DR-Scan */
\r
297 JTAG_CYCLE_TCK(); /* Capture-DR */
\r
298 JTAG_CYCLE_TCK(); /* Shift-DR */
\r
300 for (n = DAP_Data.jtag_dev.index; n; n--) {
\r
301 JTAG_CYCLE_TCK(); /* Bypass before data */
\r
305 JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */
\r
306 JTAG_CYCLE_TCK(); /* Set A2=0 */
\r
307 JTAG_CYCLE_TCK(); /* Set A3=0 */
\r
309 for (n = 31; n; n--) {
\r
310 JTAG_CYCLE_TDI(data); /* Set D0..D30 */
\r
313 n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1;
\r
315 JTAG_CYCLE_TDI(data); /* Set D31 */
\r
316 for (--n; n; n--) {
\r
317 JTAG_CYCLE_TCK(); /* Bypass after data */
\r
320 JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */
\r
323 JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */
\r
326 JTAG_CYCLE_TCK(); /* Update-DR */
\r
328 JTAG_CYCLE_TCK(); /* Idle */
\r
336 void JTAG_IR (uint32_t ir) {
\r
337 if (DAP_Data.fast_clock) {
\r
345 // JTAG Transfer I/O
\r
346 // request: A[3:2] RnW APnDP
\r
347 // data: DATA[31:0]
\r
348 // return: ACK[2:0]
\r
349 uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) {
\r
350 if (DAP_Data.fast_clock) {
\r
351 return JTAG_TransferFast(request, data);
\r
353 return JTAG_TransferSlow(request, data);
\r
358 #endif /* (DAP_JTAG != 0) */
\r