1 /******************************************************************************
\r
3 * @brief CMSIS-DAP SW DP I/O
\r
8 * Copyright (C) 2012 ARM Limited. All rights reserved.
\r
11 * ARM Limited (ARM) is supplying this software for use with Cortex-M
\r
12 * processor based microcontrollers.
\r
15 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
\r
16 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
\r
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
\r
18 * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
\r
19 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
\r
21 ******************************************************************************/
\r
23 #include "DAP_config.h"
\r
29 #define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
\r
30 #define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR
\r
32 #define SW_CLOCK_CYCLE() \
\r
38 #define SW_WRITE_BIT(bit) \
\r
39 PIN_SWDIO_OUT(bit); \
\r
45 #define SW_READ_BIT(bit) \
\r
48 bit = PIN_SWDIO_IN(); \
\r
52 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
\r
55 // Generate SWJ Sequence
\r
56 // count: sequence bit count
\r
57 // data: pointer to sequence bit data
\r
59 #if ((DAP_SWD != 0) || (DAP_JTAG != 0))
\r
60 void SWJ_Sequence (uint32_t count, uint8_t *data) {
\r
72 PIN_SWDIO_TMS_SET();
\r
74 PIN_SWDIO_TMS_CLR();
\r
88 // request: A[3:2] RnW APnDP
\r
91 #define SWD_TransferFunction(speed) /**/ \
\r
92 uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
\r
100 /* Packet Request */ \
\r
102 SW_WRITE_BIT(1); /* Start Bit */ \
\r
103 bit = request >> 0; \
\r
104 SW_WRITE_BIT(bit); /* APnDP Bit */ \
\r
106 bit = request >> 1; \
\r
107 SW_WRITE_BIT(bit); /* RnW Bit */ \
\r
109 bit = request >> 2; \
\r
110 SW_WRITE_BIT(bit); /* A2 Bit */ \
\r
112 bit = request >> 3; \
\r
113 SW_WRITE_BIT(bit); /* A3 Bit */ \
\r
115 SW_WRITE_BIT(parity); /* Parity Bit */ \
\r
116 SW_WRITE_BIT(0); /* Stop Bit */ \
\r
117 SW_WRITE_BIT(1); /* Park Bit */ \
\r
120 PIN_SWDIO_OUT_DISABLE(); \
\r
121 for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
\r
122 SW_CLOCK_CYCLE(); \
\r
125 /* Acknowledge response */ \
\r
126 SW_READ_BIT(bit); \
\r
128 SW_READ_BIT(bit); \
\r
130 SW_READ_BIT(bit); \
\r
133 if (ack == DAP_TRANSFER_OK) { /* OK response */ \
\r
134 /* Data transfer */ \
\r
135 if (request & DAP_TRANSFER_RnW) { \
\r
139 for (n = 32; n; n--) { \
\r
140 SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
\r
143 val |= bit << 31; \
\r
145 SW_READ_BIT(bit); /* Read Parity */ \
\r
146 if ((parity ^ bit) & 1) { \
\r
147 ack = DAP_TRANSFER_ERROR; \
\r
149 if (data) *data = val; \
\r
151 for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
\r
152 SW_CLOCK_CYCLE(); \
\r
154 PIN_SWDIO_OUT_ENABLE(); \
\r
157 for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
\r
158 SW_CLOCK_CYCLE(); \
\r
160 PIN_SWDIO_OUT_ENABLE(); \
\r
164 for (n = 32; n; n--) { \
\r
165 SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
\r
169 SW_WRITE_BIT(parity); /* Write Parity Bit */ \
\r
171 /* Idle cycles */ \
\r
172 n = DAP_Data.transfer.idle_cycles; \
\r
174 PIN_SWDIO_OUT(0); \
\r
176 SW_CLOCK_CYCLE(); \
\r
179 PIN_SWDIO_OUT(1); \
\r
183 if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
\r
184 /* WAIT or FAULT response */ \
\r
185 if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0)) { \
\r
186 for (n = 32+1; n; n--) { \
\r
187 SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
\r
191 for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
\r
192 SW_CLOCK_CYCLE(); \
\r
194 PIN_SWDIO_OUT_ENABLE(); \
\r
195 if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0)) { \
\r
196 PIN_SWDIO_OUT(0); \
\r
197 for (n = 32+1; n; n--) { \
\r
198 SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
\r
201 PIN_SWDIO_OUT(1); \
\r
205 /* Protocol error */ \
\r
206 for (n = DAP_Data.swd_conf.turnaround + 32 + 1; n; n--) { \
\r
207 SW_CLOCK_CYCLE(); /* Back off data phase */ \
\r
209 PIN_SWDIO_OUT(1); \
\r
215 #define PIN_DELAY() PIN_DELAY_FAST()
\r
216 SWD_TransferFunction(Fast);
\r
219 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
\r
220 SWD_TransferFunction(Slow);
\r
223 // SWD Transfer I/O
\r
224 // request: A[3:2] RnW APnDP
\r
225 // data: DATA[31:0]
\r
226 // return: ACK[2:0]
\r
227 uint8_t SWD_Transfer(uint32_t request, uint32_t *data) {
\r
228 if (DAP_Data.fast_clock) {
\r
229 return SWD_TransferFast(request, data);
\r
231 return SWD_TransferSlow(request, data);
\r
236 #endif /* (DAP_SWD != 0) */
\r