--- /dev/null
+/******************************************************************************\r
+ * @file JTAG_DP.c\r
+ * @brief CMSIS-DAP JTAG DP I/O\r
+ * @version V1.00\r
+ * @date 31. May 2012\r
+ *\r
+ * @note\r
+ * Copyright (C) 2012 ARM Limited. All rights reserved.\r
+ *\r
+ * @par\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M\r
+ * processor based microcontrollers.\r
+ *\r
+ * @par\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#include "DAP_config.h"\r
+#include "DAP.h"\r
+\r
+\r
+// JTAG Macros\r
+\r
+#define PIN_TCK_SET PIN_SWCLK_TCK_SET\r
+#define PIN_TCK_CLR PIN_SWCLK_TCK_CLR\r
+#define PIN_TMS_SET PIN_SWDIO_TMS_SET\r
+#define PIN_TMS_CLR PIN_SWDIO_TMS_CLR\r
+\r
+#define JTAG_CYCLE_TCK() \\r
+ PIN_TCK_CLR(); \\r
+ PIN_DELAY(); \\r
+ PIN_TCK_SET(); \\r
+ PIN_DELAY()\r
+\r
+#define JTAG_CYCLE_TDI(tdi) \\r
+ PIN_TDI_OUT(tdi); \\r
+ PIN_TCK_CLR(); \\r
+ PIN_DELAY(); \\r
+ PIN_TCK_SET(); \\r
+ PIN_DELAY()\r
+\r
+#define JTAG_CYCLE_TDO(tdo) \\r
+ PIN_TCK_CLR(); \\r
+ PIN_DELAY(); \\r
+ tdo = PIN_TDO_IN(); \\r
+ PIN_TCK_SET(); \\r
+ PIN_DELAY()\r
+\r
+#define JTAG_CYCLE_TDIO(tdi,tdo) \\r
+ PIN_TDI_OUT(tdi); \\r
+ PIN_TCK_CLR(); \\r
+ PIN_DELAY(); \\r
+ tdo = PIN_TDO_IN(); \\r
+ PIN_TCK_SET(); \\r
+ PIN_DELAY()\r
+\r
+#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)\r
+\r
+\r
+#if (DAP_JTAG != 0)\r
+\r
+\r
+// Generate JTAG Sequence\r
+// info: sequence information\r
+// tdi: pointer to TDI generated data\r
+// tdo: pointer to TDO captured data\r
+// return: none\r
+void JTAG_Sequence (uint32_t info, uint8_t *tdi, uint8_t *tdo) {\r
+ uint32_t i_val;\r
+ uint32_t o_val;\r
+ uint32_t bit;\r
+ uint32_t n, k;\r
+\r
+ n = info & JTAG_SEQUENCE_TCK;\r
+ if (n == 0) n = 64;\r
+\r
+ if (info & JTAG_SEQUENCE_TMS) {\r
+ PIN_TMS_SET();\r
+ } else {\r
+ PIN_TMS_CLR();\r
+ }\r
+\r
+ while (n) {\r
+ i_val = *tdi++;\r
+ o_val = 0;\r
+ for (k = 8; k && n; k--, n--) {\r
+ JTAG_CYCLE_TDIO(i_val, bit);\r
+ i_val >>= 1;\r
+ o_val >>= 1;\r
+ o_val |= bit << 7;\r
+ }\r
+ o_val >>= k;\r
+ if (info & JTAG_SEQUENCE_TDO) {\r
+ *tdo++ = o_val;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+// JTAG Set IR\r
+// ir: IR value\r
+// return: none\r
+#define JTAG_IR_Function(speed) /**/ \\r
+void JTAG_IR_##speed (uint32_t ir) { \\r
+ uint32_t n; \\r
+ \\r
+ PIN_TMS_SET(); \\r
+ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \\r
+ JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \\r
+ PIN_TMS_CLR(); \\r
+ JTAG_CYCLE_TCK(); /* Capture-IR */ \\r
+ JTAG_CYCLE_TCK(); /* Shift-IR */ \\r
+ \\r
+ PIN_TDI_OUT(1); \\r
+ for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \\r
+ JTAG_CYCLE_TCK(); /* Bypass before data */ \\r
+ } \\r
+ for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1; n; n--) { \\r
+ JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \\r
+ ir >>= 1; \\r
+ } \\r
+ n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \\r
+ if (n) { \\r
+ JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \\r
+ PIN_TDI_OUT(1); \\r
+ for (--n; n; n--) { \\r
+ JTAG_CYCLE_TCK(); /* Bypass after data */ \\r
+ } \\r
+ PIN_TMS_SET(); \\r
+ JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \\r
+ } else { \\r
+ PIN_TMS_SET(); \\r
+ JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \\r
+ } \\r
+ \\r
+ JTAG_CYCLE_TCK(); /* Update-IR */ \\r
+ PIN_TMS_CLR(); \\r
+ JTAG_CYCLE_TCK(); /* Idle */ \\r
+ PIN_TDI_OUT(1); \\r
+}\r
+\r
+\r
+// JTAG Transfer I/O\r
+// request: A[3:2] RnW APnDP\r
+// data: DATA[31:0]\r
+// return: ACK[2:0]\r
+#define JTAG_TransferFunction(speed) /**/ \\r
+uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) { \\r
+ uint32_t ack; \\r
+ uint32_t bit; \\r
+ uint32_t val; \\r
+ uint32_t n; \\r
+ \\r
+ PIN_TMS_SET(); \\r
+ JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \\r
+ PIN_TMS_CLR(); \\r
+ JTAG_CYCLE_TCK(); /* Capture-DR */ \\r
+ JTAG_CYCLE_TCK(); /* Shift-DR */ \\r
+ \\r
+ for (n = DAP_Data.jtag_dev.index; n; n--) { \\r
+ JTAG_CYCLE_TCK(); /* Bypass before data */ \\r
+ } \\r
+ \\r
+ JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \\r
+ ack = bit << 1; \\r
+ JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \\r
+ ack |= bit << 0; \\r
+ JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \\r
+ ack |= bit << 2; \\r
+ \\r
+ if (ack != DAP_TRANSFER_OK) { \\r
+ /* Exit on error */ \\r
+ PIN_TMS_SET(); \\r
+ JTAG_CYCLE_TCK(); /* Exit1-DR */ \\r
+ goto exit; \\r
+ } \\r
+ \\r
+ if (request & DAP_TRANSFER_RnW) { \\r
+ /* Read Transfer */ \\r
+ val = 0; \\r
+ for (n = 31; n; n--) { \\r
+ JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \\r
+ val |= bit << 31; \\r
+ val >>= 1; \\r
+ } \\r
+ n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1; \\r
+ if (n) { \\r
+ JTAG_CYCLE_TDO(bit); /* Get D31 */ \\r
+ for (--n; n; n--) { \\r
+ JTAG_CYCLE_TCK(); /* Bypass after data */ \\r
+ } \\r
+ PIN_TMS_SET(); \\r
+ JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \\r
+ } else { \\r
+ PIN_TMS_SET(); \\r
+ JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \\r
+ } \\r
+ val |= bit << 31; \\r
+ if (data) *data = val; \\r
+ } else { \\r
+ /* Write Transfer */ \\r
+ val = *data; \\r
+ for (n = 31; n; n--) { \\r
+ JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \\r
+ val >>= 1; \\r
+ } \\r
+ n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1; \\r
+ if (n) { \\r
+ JTAG_CYCLE_TDI(val); /* Set D31 */ \\r
+ for (--n; n; n--) { \\r
+ JTAG_CYCLE_TCK(); /* Bypass after data */ \\r
+ } \\r
+ PIN_TMS_SET(); \\r
+ JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \\r
+ } else { \\r
+ PIN_TMS_SET(); \\r
+ JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \\r
+ } \\r
+ } \\r
+ \\r
+exit: \\r
+ JTAG_CYCLE_TCK(); /* Update-DR */ \\r
+ PIN_TMS_CLR(); \\r
+ JTAG_CYCLE_TCK(); /* Idle */ \\r
+ PIN_TDI_OUT(1); \\r
+ \\r
+ /* Idle cycles */ \\r
+ n = DAP_Data.transfer.idle_cycles; \\r
+ while (n--) { \\r
+ JTAG_CYCLE_TCK(); /* Idle */ \\r
+ } \\r
+ \\r
+ return (ack); \\r
+}\r
+\r
+\r
+#undef PIN_DELAY\r
+#define PIN_DELAY() PIN_DELAY_FAST()\r
+JTAG_IR_Function(Fast);\r
+JTAG_TransferFunction(Fast);\r
+\r
+#undef PIN_DELAY\r
+#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)\r
+JTAG_IR_Function(Slow);\r
+JTAG_TransferFunction(Slow);\r
+\r
+\r
+// JTAG Read IDCODE register\r
+// return: value read\r
+uint32_t JTAG_ReadIDCode (void) {\r
+ uint32_t bit;\r
+ uint32_t val;\r
+ uint32_t n;\r
+\r
+ PIN_TMS_SET();\r
+ JTAG_CYCLE_TCK(); /* Select-DR-Scan */\r
+ PIN_TMS_CLR();\r
+ JTAG_CYCLE_TCK(); /* Capture-DR */\r
+ JTAG_CYCLE_TCK(); /* Shift-DR */\r
+\r
+ for (n = DAP_Data.jtag_dev.index; n; n--) {\r
+ JTAG_CYCLE_TCK(); /* Bypass before data */\r
+ }\r
+\r
+ val = 0;\r
+ for (n = 31; n; n--) {\r
+ JTAG_CYCLE_TDO(bit); /* Get D0..D30 */\r
+ val |= bit << 31;\r
+ val >>= 1;\r
+ }\r
+ PIN_TMS_SET();\r
+ JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */\r
+ val |= bit << 31;\r
+\r
+ JTAG_CYCLE_TCK(); /* Update-DR */\r
+ PIN_TMS_CLR();\r
+ JTAG_CYCLE_TCK(); /* Idle */\r
+\r
+ return (val);\r
+}\r
+\r
+\r
+// JTAG Write ABORT register\r
+// data: value to write\r
+// return: none\r
+void JTAG_WriteAbort (uint32_t data) {\r
+ uint32_t n;\r
+\r
+ PIN_TMS_SET();\r
+ JTAG_CYCLE_TCK(); /* Select-DR-Scan */\r
+ PIN_TMS_CLR();\r
+ JTAG_CYCLE_TCK(); /* Capture-DR */\r
+ JTAG_CYCLE_TCK(); /* Shift-DR */\r
+\r
+ for (n = DAP_Data.jtag_dev.index; n; n--) {\r
+ JTAG_CYCLE_TCK(); /* Bypass before data */\r
+ }\r
+\r
+ PIN_TDI_OUT(0);\r
+ JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */\r
+ JTAG_CYCLE_TCK(); /* Set A2=0 */\r
+ JTAG_CYCLE_TCK(); /* Set A3=0 */\r
+\r
+ for (n = 31; n; n--) {\r
+ JTAG_CYCLE_TDI(data); /* Set D0..D30 */\r
+ data >>= 1;\r
+ }\r
+ n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1;\r
+ if (n) {\r
+ JTAG_CYCLE_TDI(data); /* Set D31 */\r
+ for (--n; n; n--) {\r
+ JTAG_CYCLE_TCK(); /* Bypass after data */\r
+ }\r
+ PIN_TMS_SET();\r
+ JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */\r
+ } else {\r
+ PIN_TMS_SET();\r
+ JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */\r
+ }\r
+\r
+ JTAG_CYCLE_TCK(); /* Update-DR */\r
+ PIN_TMS_CLR();\r
+ JTAG_CYCLE_TCK(); /* Idle */\r
+ PIN_TDI_OUT(1);\r
+}\r
+\r
+\r
+// JTAG Set IR\r
+// ir: IR value\r
+// return: none\r
+void JTAG_IR (uint32_t ir) {\r
+ if (DAP_Data.fast_clock) {\r
+ JTAG_IR_Fast(ir);\r
+ } else {\r
+ JTAG_IR_Slow(ir);\r
+ }\r
+}\r
+\r
+\r
+// JTAG Transfer I/O\r
+// request: A[3:2] RnW APnDP\r
+// data: DATA[31:0]\r
+// return: ACK[2:0]\r
+uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) {\r
+ if (DAP_Data.fast_clock) {\r
+ return JTAG_TransferFast(request, data);\r
+ } else {\r
+ return JTAG_TransferSlow(request, data);\r
+ }\r
+}\r
+\r
+\r
+#endif /* (DAP_JTAG != 0) */\r