source: trunk/firmware_v4/Drivers/CMSIS/DAP/Firmware/Source/SW_DP.c

Last change on this file was 42, checked in by f.jahn, 5 days ago
File size: 13.6 KB
Line 
1/*
2 * Copyright (c) 2013-2017 ARM Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * ----------------------------------------------------------------------
19 *
20 * $Date: 1. December 2017
21 * $Revision: V2.0.0
22 *
23 * Project: CMSIS-DAP Source
24 * Title: SW_DP.c CMSIS-DAP SW DP I/O
25 *
26 *---------------------------------------------------------------------------*/
27
28#include "DAP_config.h"
29#include "DAP.h"
30
31
32// SW Macros
33
34#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
35#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR
36
37#define SW_CLOCK_CYCLE() \
38 PIN_SWCLK_CLR(); \
39 PIN_DELAY(); \
40 PIN_SWCLK_SET(); \
41 PIN_DELAY()
42
43#define SW_WRITE_BIT(bit) \
44 PIN_SWDIO_OUT(bit); \
45 PIN_SWCLK_CLR(); \
46 PIN_DELAY(); \
47 PIN_SWCLK_SET(); \
48 PIN_DELAY()
49
50#define SW_READ_BIT(bit) \
51 PIN_SWCLK_CLR(); \
52 PIN_DELAY(); \
53 bit = PIN_SWDIO_IN(); \
54 PIN_SWCLK_SET(); \
55 PIN_DELAY()
56
57#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
58
59
60// Generate SWJ Sequence
61// count: sequence bit count
62// data: pointer to sequence bit data
63// return: none
64#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
65void SWJ_Sequence (uint32_t count, const uint8_t *data) {
66 uint32_t val;
67 uint32_t n;
68
69 val = 0U;
70 n = 0U;
71 while (count--) {
72 if (n == 0U) {
73 val = *data++;
74 n = 8U;
75 }
76 if (val & 1U) {
77 PIN_SWDIO_TMS_SET();
78 } else {
79 PIN_SWDIO_TMS_CLR();
80 }
81 SW_CLOCK_CYCLE();
82 val >>= 1;
83 n--;
84 }
85}
86#endif
87
88
89// Generate SWD Sequence
90// info: sequence information
91// swdo: pointer to SWDIO generated data
92// swdi: pointer to SWDIO captured data
93// return: none
94#if (DAP_SWD != 0)
95void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) {
96 uint32_t val;
97 uint32_t bit;
98 uint32_t n, k;
99
100 n = info & SWD_SEQUENCE_CLK;
101 if (n == 0U) {
102 n = 64U;
103 }
104
105 if (info & SWD_SEQUENCE_DIN) {
106 while (n) {
107 val = 0U;
108 for (k = 8U; k && n; k--, n--) {
109 SW_READ_BIT(bit);
110 val >>= 1;
111 val |= bit << 7;
112 }
113 val >>= k;
114 *swdi++ = (uint8_t)val;
115 }
116 } else {
117 while (n) {
118 val = *swdo++;
119 for (k = 8U; k && n; k--, n--) {
120 SW_WRITE_BIT(val);
121 val >>= 1;
122 }
123 }
124 }
125}
126#endif
127
128
129#if (DAP_SWD != 0)
130
131
132// SWD Transfer I/O
133// request: A[3:2] RnW APnDP
134// data: DATA[31:0]
135// return: ACK[2:0]
136#define SWD_TransferFunction(speed) /**/ \
137static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
138 uint32_t ack; \
139 uint32_t bit; \
140 uint32_t val; \
141 uint32_t parity; \
142 \
143 uint32_t n; \
144 \
145 /* Packet Request */ \
146 parity = 0U; \
147 SW_WRITE_BIT(1U); /* Start Bit */ \
148 bit = request >> 0; \
149 SW_WRITE_BIT(bit); /* APnDP Bit */ \
150 parity += bit; \
151 bit = request >> 1; \
152 SW_WRITE_BIT(bit); /* RnW Bit */ \
153 parity += bit; \
154 bit = request >> 2; \
155 SW_WRITE_BIT(bit); /* A2 Bit */ \
156 parity += bit; \
157 bit = request >> 3; \
158 SW_WRITE_BIT(bit); /* A3 Bit */ \
159 parity += bit; \
160 SW_WRITE_BIT(parity); /* Parity Bit */ \
161 SW_WRITE_BIT(0U); /* Stop Bit */ \
162 SW_WRITE_BIT(1U); /* Park Bit */ \
163 \
164 /* Turnaround */ \
165 PIN_SWDIO_OUT_DISABLE(); \
166 for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
167 SW_CLOCK_CYCLE(); \
168 } \
169 \
170 /* Acknowledge response */ \
171 SW_READ_BIT(bit); \
172 ack = bit << 0; \
173 SW_READ_BIT(bit); \
174 ack |= bit << 1; \
175 SW_READ_BIT(bit); \
176 ack |= bit << 2; \
177 \
178 if (ack == DAP_TRANSFER_OK) { /* OK response */ \
179 /* Data transfer */ \
180 if (request & DAP_TRANSFER_RnW) { \
181 /* Read data */ \
182 val = 0U; \
183 parity = 0U; \
184 for (n = 32U; n; n--) { \
185 SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
186 parity += bit; \
187 val >>= 1; \
188 val |= bit << 31; \
189 } \
190 SW_READ_BIT(bit); /* Read Parity */ \
191 if ((parity ^ bit) & 1U) { \
192 ack = DAP_TRANSFER_ERROR; \
193 } \
194 if (data) { *data = val; } \
195 /* Turnaround */ \
196 for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
197 SW_CLOCK_CYCLE(); \
198 } \
199 PIN_SWDIO_OUT_ENABLE(); \
200 } else { \
201 /* Turnaround */ \
202 for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
203 SW_CLOCK_CYCLE(); \
204 } \
205 PIN_SWDIO_OUT_ENABLE(); \
206 /* Write data */ \
207 val = *data; \
208 parity = 0U; \
209 for (n = 32U; n; n--) { \
210 SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
211 parity += val; \
212 val >>= 1; \
213 } \
214 SW_WRITE_BIT(parity); /* Write Parity Bit */ \
215 } \
216 /* Capture Timestamp */ \
217 if (request & DAP_TRANSFER_TIMESTAMP) { \
218 DAP_Data.timestamp = TIMESTAMP_GET(); \
219 } \
220 /* Idle cycles */ \
221 n = DAP_Data.transfer.idle_cycles; \
222 if (n) { \
223 PIN_SWDIO_OUT(0U); \
224 for (; n; n--) { \
225 SW_CLOCK_CYCLE(); \
226 } \
227 } \
228 PIN_SWDIO_OUT(1U); \
229 return ((uint8_t)ack); \
230 } \
231 \
232 if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
233 /* WAIT or FAULT response */ \
234 if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \
235 for (n = 32U+1U; n; n--) { \
236 SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
237 } \
238 } \
239 /* Turnaround */ \
240 for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
241 SW_CLOCK_CYCLE(); \
242 } \
243 PIN_SWDIO_OUT_ENABLE(); \
244 if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
245 PIN_SWDIO_OUT(0U); \
246 for (n = 32U+1U; n; n--) { \
247 SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
248 } \
249 } \
250 PIN_SWDIO_OUT(1U); \
251 return ((uint8_t)ack); \
252 } \
253 \
254 /* Protocol error */ \
255 for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \
256 SW_CLOCK_CYCLE(); /* Back off data phase */ \
257 } \
258 PIN_SWDIO_OUT_ENABLE(); \
259 PIN_SWDIO_OUT(1U); \
260 return ((uint8_t)ack); \
261}
262
263
264#undef PIN_DELAY
265#define PIN_DELAY() PIN_DELAY_FAST()
266SWD_TransferFunction(Fast)
267
268#undef PIN_DELAY
269#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
270SWD_TransferFunction(Slow)
271
272
273// SWD Transfer I/O
274// request: A[3:2] RnW APnDP
275// data: DATA[31:0]
276// return: ACK[2:0]
277uint8_t SWD_Transfer(uint32_t request, uint32_t *data) {
278 if (DAP_Data.fast_clock) {
279 return SWD_TransferFast(request, data);
280 } else {
281 return SWD_TransferSlow(request, data);
282 }
283}
284
285
286#endif /* (DAP_SWD != 0) */
Note: See TracBrowser for help on using the repository browser.