1
2
3
6
7
8
9
10
11
12
13
16
17
18
19
20
21
22
23
24
25
28
29
30
31
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
58
65
66
72
85
86
90
91
98
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
153
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
182
183
184
185
186
187
188
189
190
191
192
199
200
201
202
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/* ... */
#ifndef OPENOCD_JTAG_SWD_H
#define OPENOCD_JTAG_SWD_H
#include <helper/log.h>
#include <target/arm_adi_v5.h>
/* ... */
#define SWD_CMD_START (1 << 0)
#define SWD_CMD_APNDP (1 << 1)
#define SWD_CMD_RNW (1 << 2)
#define SWD_CMD_A32 (3 << 3)
#define SWD_CMD_PARITY (1 << 5)
#define SWD_CMD_STOP (0 << 6)
#define SWD_CMD_PARK (1 << 7)
/* ... */
#define ERROR_SWD_FAIL (-400)
#define ERROR_SWD_FAULT (-401)
9 defines
/* ... */
static inline uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum)
{
uint8_t cmd = (is_ap ? SWD_CMD_APNDP : 0)
| (is_read ? SWD_CMD_RNW : 0)
| ((regnum & 0xc) << 1);
if (parity_u32(cmd))
cmd |= SWD_CMD_PARITY;
return cmd;
}{ ... }
/* ... */
static inline bool swd_cmd_returns_ack(uint8_t cmd)
{
uint8_t base_cmd = cmd & (SWD_CMD_APNDP | SWD_CMD_RNW | SWD_CMD_A32);
return base_cmd != swd_cmd(false, false, DP_TARGETSEL);
}{ ... }
/* ... */
static inline int swd_ack_to_error_code(uint8_t ack)
{
switch (ack) {
case SWD_ACK_OK:
return ERROR_OK;case SWD_ACK_OK:
case SWD_ACK_WAIT:
return ERROR_WAIT;case SWD_ACK_WAIT:
case SWD_ACK_FAULT:
return ERROR_SWD_FAULT;case SWD_ACK_FAULT:
default:
return ERROR_SWD_FAIL;default
}switch (ack) { ... }
}{ ... }
/* ... */
/* ... */
static const uint8_t swd_seq_line_reset[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00,
...};
static const unsigned swd_seq_line_reset_len = 64;
/* ... */
static const uint8_t swd_seq_jtag_to_swd[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x9e, 0xe7,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00,
...};
static const unsigned swd_seq_jtag_to_swd_len = 136;
/* ... */
static const uint8_t swd_seq_swd_to_jtag[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x3c, 0xe7,
0xff,
...};
static const unsigned swd_seq_swd_to_jtag_len = 80;
/* ... */
static const uint8_t swd_seq_swd_to_dormant[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xbc, 0xe3,
...};
static const unsigned swd_seq_swd_to_dormant_len = 72;
/* ... */
static const uint8_t swd_seq_dormant_to_swd[] = {
0xff,
0x92, 0xf3, 0x09, 0x62, 0x95, 0x2d, 0x85, 0x86,
0xe9, 0xaf, 0xdd, 0xe3, 0xa2, 0x0e, 0xbc, 0x19,
/* ... */
0xa0,
0xf1,
0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00,
...};
static const unsigned swd_seq_dormant_to_swd_len = 224;
/* ... */
static const uint8_t swd_seq_jtag_to_dormant[] = {
0xff,
/* ... */
0x75,
0x77,
0x77,
0x67,
...};
static const unsigned swd_seq_jtag_to_dormant_len = 40;
/* ... */
static const uint8_t swd_seq_dormant_to_jtag[] = {
0xff,
0x92, 0xf3, 0x09, 0x62, 0x95, 0x2d, 0x85, 0x86,
0xe9, 0xaf, 0xdd, 0xe3, 0xa2, 0x0e, 0xbc, 0x19,
/* ... */
0x00, 0x00,
0x00,
...};
static const unsigned swd_seq_dormant_to_jtag_len = 160;
struct swd_driver {
/* ... */
int (*init)(void);
/* ... */
int (*switch_seq)(enum swd_special_seq seq);
/* ... */
void (*read_reg)(uint8_t cmd, uint32_t *value, uint32_t ap_delay_hint);
/* ... */
void (*write_reg)(uint8_t cmd, uint32_t value, uint32_t ap_delay_hint);
/* ... */
int (*run)(void);
/* ... */
int *(*trace)(bool swo);
...};
int swd_init_reset(struct command_context *cmd_ctx);
/* ... */
#endif