--- /dev/null
+/******************************************************************************\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