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