]> git.sur5r.net Git - armstart-ibdap/blobdiff - src/SW_DP.c
initial commit
[armstart-ibdap] / src / SW_DP.c
diff --git a/src/SW_DP.c b/src/SW_DP.c
new file mode 100644 (file)
index 0000000..9dec094
--- /dev/null
@@ -0,0 +1,236 @@
+/******************************************************************************\r
+ * @file     SW_DP.c\r
+ * @brief    CMSIS-DAP SW 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
+// SW Macros\r
+\r
+#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET\r
+#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR\r
+\r
+#define SW_CLOCK_CYCLE()                \\r
+  PIN_SWCLK_CLR();                      \\r
+  PIN_DELAY();                          \\r
+  PIN_SWCLK_SET();                      \\r
+  PIN_DELAY()\r
+\r
+#define SW_WRITE_BIT(bit)               \\r
+  PIN_SWDIO_OUT(bit);                   \\r
+  PIN_SWCLK_CLR();                      \\r
+  PIN_DELAY();                          \\r
+  PIN_SWCLK_SET();                      \\r
+  PIN_DELAY()\r
+\r
+#define SW_READ_BIT(bit)                \\r
+  PIN_SWCLK_CLR();                      \\r
+  PIN_DELAY();                          \\r
+  bit = PIN_SWDIO_IN();                 \\r
+  PIN_SWCLK_SET();                      \\r
+  PIN_DELAY()\r
+\r
+#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)\r
+\r
+\r
+// Generate SWJ Sequence\r
+//   count:  sequence bit count\r
+//   data:   pointer to sequence bit data\r
+//   return: none\r
+#if ((DAP_SWD != 0) || (DAP_JTAG != 0))\r
+void SWJ_Sequence (uint32_t count, uint8_t *data) {\r
+  uint32_t val;\r
+  uint32_t n;\r
+\r
+  val = 0;\r
+  n = 0;\r
+  while (count--) {\r
+    if (n == 0) {\r
+      val = *data++;\r
+      n = 8;\r
+    }\r
+    if (val & 1) {\r
+      PIN_SWDIO_TMS_SET();\r
+    } else {\r
+      PIN_SWDIO_TMS_CLR();\r
+    }\r
+    SW_CLOCK_CYCLE();\r
+    val >>= 1;\r
+    n--;\r
+  }\r
+}\r
+#endif\r
+\r
+\r
+#if (DAP_SWD != 0)\r
+\r
+\r
+// SWD Transfer I/O\r
+//   request: A[3:2] RnW APnDP\r
+//   data:    DATA[31:0]\r
+//   return:  ACK[2:0]\r
+#define SWD_TransferFunction(speed)     /**/                                    \\r
+uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) {                \\r
+  uint32_t ack;                                                                 \\r
+  uint32_t bit;                                                                 \\r
+  uint32_t val;                                                                 \\r
+  uint32_t parity;                                                              \\r
+                                                                                \\r
+  uint32_t n;                                                                   \\r
+                                                                                \\r
+  /* Packet Request */                                                          \\r
+  parity = 0;                                                                   \\r
+  SW_WRITE_BIT(1);                      /* Start Bit */                         \\r
+  bit = request >> 0;                                                           \\r
+  SW_WRITE_BIT(bit);                    /* APnDP Bit */                         \\r
+  parity += bit;                                                                \\r
+  bit = request >> 1;                                                           \\r
+  SW_WRITE_BIT(bit);                    /* RnW Bit */                           \\r
+  parity += bit;                                                                \\r
+  bit = request >> 2;                                                           \\r
+  SW_WRITE_BIT(bit);                    /* A2 Bit */                            \\r
+  parity += bit;                                                                \\r
+  bit = request >> 3;                                                           \\r
+  SW_WRITE_BIT(bit);                    /* A3 Bit */                            \\r
+  parity += bit;                                                                \\r
+  SW_WRITE_BIT(parity);                 /* Parity Bit */                        \\r
+  SW_WRITE_BIT(0);                      /* Stop Bit */                          \\r
+  SW_WRITE_BIT(1);                      /* Park Bit */                          \\r
+                                                                                \\r
+  /* Turnaround */                                                              \\r
+  PIN_SWDIO_OUT_DISABLE();                                                      \\r
+  for (n = DAP_Data.swd_conf.turnaround; n; n--) {                              \\r
+    SW_CLOCK_CYCLE();                                                           \\r
+  }                                                                             \\r
+                                                                                \\r
+  /* Acknowledge response */                                                    \\r
+  SW_READ_BIT(bit);                                                             \\r
+  ack  = bit << 0;                                                              \\r
+  SW_READ_BIT(bit);                                                             \\r
+  ack |= bit << 1;                                                              \\r
+  SW_READ_BIT(bit);                                                             \\r
+  ack |= bit << 2;                                                              \\r
+                                                                                \\r
+  if (ack == DAP_TRANSFER_OK) {         /* OK response */                       \\r
+    /* Data transfer */                                                         \\r
+    if (request & DAP_TRANSFER_RnW) {                                           \\r
+      /* Read data */                                                           \\r
+      val = 0;                                                                  \\r
+      parity = 0;                                                               \\r
+      for (n = 32; n; n--) {                                                    \\r
+        SW_READ_BIT(bit);               /* Read RDATA[0:31] */                  \\r
+        parity += bit;                                                          \\r
+        val >>= 1;                                                              \\r
+        val  |= bit << 31;                                                      \\r
+      }                                                                         \\r
+      SW_READ_BIT(bit);                 /* Read Parity */                       \\r
+      if ((parity ^ bit) & 1) {                                                 \\r
+        ack = DAP_TRANSFER_ERROR;                                               \\r
+      }                                                                         \\r
+      if (data) *data = val;                                                    \\r
+      /* Turnaround */                                                          \\r
+      for (n = DAP_Data.swd_conf.turnaround; n; n--) {                          \\r
+        SW_CLOCK_CYCLE();                                                       \\r
+      }                                                                         \\r
+      PIN_SWDIO_OUT_ENABLE();                                                   \\r
+    } else {                                                                    \\r
+      /* Turnaround */                                                          \\r
+      for (n = DAP_Data.swd_conf.turnaround; n; n--) {                          \\r
+        SW_CLOCK_CYCLE();                                                       \\r
+      }                                                                         \\r
+      PIN_SWDIO_OUT_ENABLE();                                                   \\r
+      /* Write data */                                                          \\r
+      val = *data;                                                              \\r
+      parity = 0;                                                               \\r
+      for (n = 32; n; n--) {                                                    \\r
+        SW_WRITE_BIT(val);              /* Write WDATA[0:31] */                 \\r
+        parity += val;                                                          \\r
+        val >>= 1;                                                              \\r
+      }                                                                         \\r
+      SW_WRITE_BIT(parity);             /* Write Parity Bit */                  \\r
+    }                                                                           \\r
+    /* Idle cycles */                                                           \\r
+    n = DAP_Data.transfer.idle_cycles;                                          \\r
+    if (n) {                                                                    \\r
+      PIN_SWDIO_OUT(0);                                                         \\r
+      for (; n; n--) {                                                          \\r
+        SW_CLOCK_CYCLE();                                                       \\r
+      }                                                                         \\r
+    }                                                                           \\r
+    PIN_SWDIO_OUT(1);                                                           \\r
+    return (ack);                                                               \\r
+  }                                                                             \\r
+                                                                                \\r
+  if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {              \\r
+    /* WAIT or FAULT response */                                                \\r
+    if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0)) {  \\r
+      for (n = 32+1; n; n--) {                                                  \\r
+        SW_CLOCK_CYCLE();               /* Dummy Read RDATA[0:31] + Parity */   \\r
+      }                                                                         \\r
+    }                                                                           \\r
+    /* Turnaround */                                                            \\r
+    for (n = DAP_Data.swd_conf.turnaround; n; n--) {                            \\r
+      SW_CLOCK_CYCLE();                                                         \\r
+    }                                                                           \\r
+    PIN_SWDIO_OUT_ENABLE();                                                     \\r
+    if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0)) {  \\r
+      PIN_SWDIO_OUT(0);                                                         \\r
+      for (n = 32+1; n; n--) {                                                  \\r
+        SW_CLOCK_CYCLE();               /* Dummy Write WDATA[0:31] + Parity */  \\r
+      }                                                                         \\r
+    }                                                                           \\r
+    PIN_SWDIO_OUT(1);                                                           \\r
+    return (ack);                                                               \\r
+  }                                                                             \\r
+                                                                                \\r
+  /* Protocol error */                                                          \\r
+  for (n = DAP_Data.swd_conf.turnaround + 32 + 1; n; n--) {                     \\r
+    SW_CLOCK_CYCLE();                   /* Back off data phase */               \\r
+  }                                                                             \\r
+  PIN_SWDIO_OUT(1);                                                             \\r
+  return (ack);                                                                 \\r
+}\r
+\r
+\r
+#undef  PIN_DELAY\r
+#define PIN_DELAY() PIN_DELAY_FAST()\r
+SWD_TransferFunction(Fast);\r
+\r
+#undef  PIN_DELAY\r
+#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)\r
+SWD_TransferFunction(Slow);\r
+\r
+\r
+// SWD Transfer I/O\r
+//   request: A[3:2] RnW APnDP\r
+//   data:    DATA[31:0]\r
+//   return:  ACK[2:0]\r
+uint8_t  SWD_Transfer(uint32_t request, uint32_t *data) {\r
+  if (DAP_Data.fast_clock) {\r
+    return SWD_TransferFast(request, data);\r
+  } else {\r
+    return SWD_TransferSlow(request, data);\r
+  }\r
+}\r
+\r
+\r
+#endif  /* (DAP_SWD != 0) */\r