]> git.sur5r.net Git - armstart-ibdap/blobdiff - src/JTAG_DP.c
initial commit
[armstart-ibdap] / src / JTAG_DP.c
diff --git a/src/JTAG_DP.c b/src/JTAG_DP.c
new file mode 100644 (file)
index 0000000..9d6692b
--- /dev/null
@@ -0,0 +1,358 @@
+/******************************************************************************\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