1 /*
2 * Copyright (c) 2018-2019 PHYTEC Messtechnik GmbH
3 * Copyright (c) 2023 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 /*
9 * This file is based on DAP.c from CMSIS-DAP Source (Revision: V2.0.0)
10 * https://github.com/ARM-software/CMSIS_5/tree/develop/CMSIS/DAP/Firmware
11 * Copyright (c) 2013-2017 ARM Limited. All rights reserved.
12 * SPDX-License-Identifier: Apache-2.0
13 */
14
15 #include <string.h>
16 #include <zephyr/kernel.h>
17 #include <zephyr/device.h>
18 #include <zephyr/init.h>
19 #include <zephyr/sys/byteorder.h>
20 #include <zephyr/drivers/swdp.h>
21 #include <stdint.h>
22
23 #include <cmsis_dap.h>
24
25 #include <zephyr/logging/log.h>
26 LOG_MODULE_REGISTER(dap, CONFIG_DAP_LOG_LEVEL);
27
28 #define DAP_STATE_CONNECTED 0
29
30 struct dap_context {
31 struct device *swdp_dev;
32 atomic_t state;
33 uint8_t debug_port;
34 uint8_t capabilities;
35 uint16_t pkt_size;
36 struct {
37 /* Idle cycles after transfer */
38 uint8_t idle_cycles;
39 /* Number of retries after WAIT response */
40 uint16_t retry_count;
41 /* Number of retries if read value does not match */
42 uint16_t match_retry;
43 /* Match Mask */
44 uint32_t match_mask;
45 } transfer;
46 };
47
48 static struct dap_context dap_ctx[1];
49
50 BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_PROBE_VENDOR) <=
51 MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
52 "PROBE_VENDOR string is too long.");
53 BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_PROBE_NAME) <=
54 MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
55 "PROBE_NAME string is too long.");
56 BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_BOARD_VENDOR) <=
57 MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
58 "BOARD_VENDOR string is too long.");
59 BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_BOARD_NAME) <=
60 MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
61 "BOARD_NAME string is too long.");
62 BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_DEVICE_VENDOR) <=
63 MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
64 "DEVICE_VENDOR string is too long.");
65 BUILD_ASSERT(sizeof(CONFIG_CMSIS_DAP_DEVICE_NAME) <=
66 MIN(CONFIG_CMSIS_DAP_PACKET_SIZE - 2, UINT8_MAX - 2),
67 "DEVICE_NAME string is too long.");
68
69 /* Get DAP Information */
dap_info(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)70 static uint16_t dap_info(struct dap_context *const ctx,
71 const uint8_t *const request,
72 uint8_t *const response)
73 {
74 uint8_t *info = response + 1;
75 uint8_t id = request[0];
76 uint8_t length = 0U;
77
78 switch (id) {
79 case DAP_ID_VENDOR:
80 LOG_DBG("ID_VENDOR");
81 memcpy(info, CONFIG_CMSIS_DAP_PROBE_VENDOR,
82 sizeof(CONFIG_CMSIS_DAP_PROBE_VENDOR));
83 length = sizeof(CONFIG_CMSIS_DAP_PROBE_VENDOR);
84 break;
85 case DAP_ID_PRODUCT:
86 LOG_DBG("ID_PRODUCT");
87 memcpy(info, CONFIG_CMSIS_DAP_PROBE_NAME,
88 sizeof(CONFIG_CMSIS_DAP_PROBE_NAME));
89 length = sizeof(CONFIG_CMSIS_DAP_PROBE_NAME);
90 break;
91 case DAP_ID_SER_NUM:
92 /* optional to implement */
93 LOG_DBG("ID_SER_NUM unsupported");
94 break;
95 case DAP_ID_FW_VER:
96 LOG_DBG("ID_FW_VER");
97 memcpy(info, DAP_FW_VER, sizeof(DAP_FW_VER));
98 length = sizeof(DAP_FW_VER);
99 break;
100 case DAP_ID_DEVICE_VENDOR:
101 LOG_DBG("ID_DEVICE_VENDOR");
102 memcpy(info, CONFIG_CMSIS_DAP_DEVICE_VENDOR,
103 sizeof(CONFIG_CMSIS_DAP_DEVICE_VENDOR));
104 length = sizeof(CONFIG_CMSIS_DAP_DEVICE_VENDOR);
105 break;
106 case DAP_ID_DEVICE_NAME:
107 LOG_DBG("ID_DEVICE_NAME");
108 memcpy(info, CONFIG_CMSIS_DAP_DEVICE_NAME,
109 sizeof(CONFIG_CMSIS_DAP_DEVICE_NAME));
110 length = sizeof(CONFIG_CMSIS_DAP_DEVICE_NAME);
111 break;
112 case DAP_ID_BOARD_VENDOR:
113 LOG_DBG("ID_BOARD_VENDOR");
114 memcpy(info, CONFIG_CMSIS_DAP_BOARD_VENDOR,
115 sizeof(CONFIG_CMSIS_DAP_BOARD_VENDOR));
116 length = sizeof(CONFIG_CMSIS_DAP_BOARD_VENDOR);
117 break;
118 case DAP_ID_BOARD_NAME:
119 memcpy(info, CONFIG_CMSIS_DAP_BOARD_NAME,
120 sizeof(CONFIG_CMSIS_DAP_BOARD_NAME));
121 length = sizeof(CONFIG_CMSIS_DAP_BOARD_NAME);
122 LOG_DBG("ID_BOARD_NAME");
123 break;
124 case DAP_ID_PRODUCT_FW_VER:
125 /* optional to implement */
126 LOG_DBG("ID_PRODUCT_FW_VER unsupported");
127 break;
128 case DAP_ID_CAPABILITIES:
129 info[0] = ctx->capabilities;
130 LOG_DBG("ID_CAPABILITIES 0x%0x", info[0]);
131 length = 1U;
132 break;
133 case DAP_ID_TIMESTAMP_CLOCK:
134 LOG_DBG("ID_TIMESTAMP_CLOCK unsupported");
135 break;
136 case DAP_ID_UART_RX_BUFFER_SIZE:
137 LOG_DBG("ID_UART_RX_BUFFER_SIZE unsupported");
138 break;
139 case DAP_ID_UART_TX_BUFFER_SIZE:
140 LOG_DBG("ID_UART_TX_BUFFER_SIZE unsupported");
141 break;
142 case DAP_ID_SWO_BUFFER_SIZE:
143 LOG_DBG("ID_SWO_BUFFER_SIZE unsupported");
144 break;
145 case DAP_ID_PACKET_SIZE:
146 LOG_DBG("ID_PACKET_SIZE");
147 sys_put_le16(ctx->pkt_size, &info[0]);
148 length = 2U;
149 break;
150 case DAP_ID_PACKET_COUNT:
151 LOG_DBG("ID_PACKET_COUNT");
152 info[0] = CONFIG_CMSIS_DAP_PACKET_COUNT;
153 length = 1U;
154 break;
155 default:
156 LOG_DBG("unsupported ID");
157 break;
158 }
159
160 response[0] = length;
161
162 return length + 1U;
163 }
164
165 /* Process Host Status command and prepare response */
dap_host_status(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)166 static uint16_t dap_host_status(struct dap_context *const ctx,
167 const uint8_t *const request,
168 uint8_t *const response)
169 {
170 switch (request[0]) {
171 case DAP_DEBUGGER_CONNECTED:
172 if (request[1]) {
173 LOG_INF("Debugger connected");
174 } else {
175 LOG_INF("Debugger disconnected");
176 }
177 break;
178 case DAP_TARGET_RUNNING:
179 LOG_DBG("unsupported");
180 break;
181 default:
182 *response = DAP_ERROR;
183 return 1U;
184 }
185
186 response[0] = DAP_OK;
187 return 1U;
188 }
189
190 /* Process Connect command and prepare response */
dap_connect(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)191 static uint16_t dap_connect(struct dap_context *const ctx,
192 const uint8_t *const request,
193 uint8_t *const response)
194 {
195 const struct swdp_api *api = ctx->swdp_dev->api;
196 uint8_t port;
197
198 if (request[0] == DAP_PORT_AUTODETECT) {
199 port = DAP_PORT_SWD;
200 } else {
201 port = request[0];
202 }
203
204 switch (port) {
205 case DAP_PORT_SWD:
206 LOG_INF("port swd");
207 ctx->debug_port = DAP_PORT_SWD;
208
209 if (atomic_test_and_set_bit(&ctx->state,
210 DAP_STATE_CONNECTED)) {
211 LOG_ERR("DAP device is already connected");
212 break;
213 }
214
215 api->swdp_port_on(ctx->swdp_dev);
216 break;
217 case DAP_PORT_JTAG:
218 LOG_ERR("port unsupported");
219 port = DAP_ERROR;
220 break;
221 default:
222 LOG_DBG("port disabled");
223 port = DAP_PORT_DISABLED;
224 break;
225 }
226
227 response[0] = port;
228 return 1U;
229 }
230
231 /* Process Disconnect command and prepare response */
dap_disconnect(struct dap_context * const ctx,uint8_t * const response)232 static uint16_t dap_disconnect(struct dap_context *const ctx,
233 uint8_t *const response)
234 {
235 const struct swdp_api *api = ctx->swdp_dev->api;
236
237 LOG_DBG("");
238
239 ctx->debug_port = DAP_PORT_DISABLED;
240
241 if (atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
242 api->swdp_port_off(ctx->swdp_dev);
243 } else {
244 LOG_WRN("DAP device is not connected");
245 }
246
247 response[0] = DAP_OK;
248 atomic_clear_bit(&ctx->state, DAP_STATE_CONNECTED);
249
250 return 1;
251 }
252
253 /* Process Delay command and prepare response */
dap_delay(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)254 static uint16_t dap_delay(struct dap_context *const ctx,
255 const uint8_t *const request,
256 uint8_t *const response)
257 {
258 uint16_t delay = sys_get_le16(&request[0]);
259
260 LOG_DBG("dap delay %u ms", delay);
261
262 k_busy_wait(delay * USEC_PER_MSEC);
263 response[0] = DAP_OK;
264
265 return 1U;
266 }
267
268 /* Process Reset Target command and prepare response */
dap_reset_target(struct dap_context * const ctx,uint8_t * const response)269 static uint16_t dap_reset_target(struct dap_context *const ctx,
270 uint8_t *const response)
271 {
272 response[0] = DAP_OK;
273 response[1] = 0U;
274 LOG_WRN("unsupported");
275
276 return 2;
277 }
278
279 /* Process SWJ Pins command and prepare response */
dap_swj_pins(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)280 static uint16_t dap_swj_pins(struct dap_context *const ctx,
281 const uint8_t *const request,
282 uint8_t *const response)
283 {
284 const struct swdp_api *api = ctx->swdp_dev->api;
285 uint8_t value = request[0];
286 uint8_t select = request[1];
287 uint32_t wait = sys_get_le32(&request[2]);
288 k_timepoint_t end = sys_timepoint_calc(K_USEC(wait));
289 uint8_t state;
290
291 if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
292 LOG_ERR("DAP device is not connected");
293 response[0] = DAP_ERROR;
294 return 1U;
295 }
296
297 /* Skip if nothing selected. */
298 if (select) {
299 api->swdp_set_pins(ctx->swdp_dev, select, value);
300 }
301
302 do {
303 api->swdp_get_pins(ctx->swdp_dev, &state);
304 LOG_INF("select 0x%02x, value 0x%02x, wait %u, state 0x%02x",
305 select, value, wait, state);
306 if ((value & select) == (state & select)) {
307 LOG_DBG("swdp_get_pins succeeded before timeout");
308 break;
309 }
310 } while (!sys_timepoint_expired(end));
311
312 response[0] = state;
313
314 return sizeof(state);
315 }
316
317 /* Process SWJ Clock command and prepare response */
dap_swj_clock(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)318 static uint16_t dap_swj_clock(struct dap_context *const ctx,
319 const uint8_t *const request,
320 uint8_t *const response)
321 {
322 const struct swdp_api *api = ctx->swdp_dev->api;
323 uint32_t clk = sys_get_le32(&request[0]);
324
325 LOG_DBG("clock %d", clk);
326
327 if (atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
328 if (clk) {
329 api->swdp_set_clock(ctx->swdp_dev, clk);
330 response[0] = DAP_OK;
331 } else {
332 response[0] = DAP_ERROR;
333 }
334 } else {
335 LOG_WRN("DAP device is not connected");
336 response[0] = DAP_OK;
337 }
338
339 return 1U;
340 }
341
342 /* Process SWJ Sequence command and prepare response */
dap_swj_sequence(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)343 static uint16_t dap_swj_sequence(struct dap_context *const ctx,
344 const uint8_t *const request,
345 uint8_t *const response)
346 {
347 const struct swdp_api *api = ctx->swdp_dev->api;
348 uint16_t count = request[0];
349
350 LOG_DBG("count %u", count);
351
352 if (count == 0U) {
353 count = 256U;
354 }
355
356 if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
357 LOG_ERR("DAP device is not connected");
358 response[0] = DAP_ERROR;
359 return 1U;
360 }
361
362 api->swdp_output_sequence(ctx->swdp_dev, count, &request[1]);
363 response[0] = DAP_OK;
364
365 return 1U;
366 }
367
368 /* Process SWD Configure command and prepare response */
dap_swdp_configure(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)369 static uint16_t dap_swdp_configure(struct dap_context *const ctx,
370 const uint8_t *const request,
371 uint8_t *const response)
372 {
373 const struct swdp_api *api = ctx->swdp_dev->api;
374 uint8_t turnaround = (request[0] & 0x03U) + 1U;
375 bool data_phase = (request[0] & 0x04U) ? true : false;
376
377 if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
378 LOG_ERR("DAP device is not connected");
379 response[0] = DAP_ERROR;
380 return 1U;
381 }
382
383 api->swdp_configure(ctx->swdp_dev, turnaround, data_phase);
384 response[0] = DAP_OK;
385
386 return 1U;
387 }
388
389 /* Process Transfer Configure command and prepare response */
dap_transfer_cfg(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)390 static uint16_t dap_transfer_cfg(struct dap_context *const ctx,
391 const uint8_t *const request,
392 uint8_t *const response)
393 {
394
395 ctx->transfer.idle_cycles = request[0];
396 ctx->transfer.retry_count = sys_get_le16(&request[1]);
397 ctx->transfer.match_retry = sys_get_le16(&request[3]);
398 LOG_DBG("idle_cycles %d, retry_count %d, match_retry %d",
399 ctx->transfer.idle_cycles,
400 ctx->transfer.retry_count,
401 ctx->transfer.match_retry);
402
403 response[0] = DAP_OK;
404 return 1U;
405 }
406
do_swdp_transfer(struct dap_context * const ctx,const uint8_t req_val,uint32_t * data)407 static inline uint8_t do_swdp_transfer(struct dap_context *const ctx,
408 const uint8_t req_val,
409 uint32_t *data)
410 {
411 const struct swdp_api *api = ctx->swdp_dev->api;
412 uint32_t retry = ctx->transfer.retry_count;
413 uint8_t rspns_val;
414
415 do {
416 api->swdp_transfer(ctx->swdp_dev,
417 req_val,
418 data,
419 ctx->transfer.idle_cycles,
420 &rspns_val);
421 } while ((rspns_val == SWDP_ACK_WAIT) && retry--);
422
423 return rspns_val;
424 }
425
swdp_transfer_match(struct dap_context * const ctx,const uint8_t req_val,const uint32_t match_val)426 static uint8_t swdp_transfer_match(struct dap_context *const ctx,
427 const uint8_t req_val,
428 const uint32_t match_val)
429 {
430 uint32_t match_retry = ctx->transfer.match_retry;
431 uint32_t data;
432 uint8_t rspns_val;
433
434 if (req_val & SWDP_REQUEST_APnDP) {
435 /* Post AP read, result will be returned on the next transfer */
436 rspns_val = do_swdp_transfer(ctx, req_val, NULL);
437 if (rspns_val != SWDP_ACK_OK) {
438 return rspns_val;
439 }
440 }
441
442 do {
443 /*
444 * Read register until its value matches
445 * or retry counter expires
446 */
447 rspns_val = do_swdp_transfer(ctx, req_val, &data);
448 if (rspns_val != SWDP_ACK_OK) {
449 return rspns_val;
450 }
451
452 } while (((data & ctx->transfer.match_mask) != match_val) &&
453 match_retry--);
454
455 if ((data & ctx->transfer.match_mask) != match_val) {
456 rspns_val |= DAP_TRANSFER_MISMATCH;
457 }
458
459 return rspns_val;
460 }
461
462 /*
463 * Process SWD Transfer command and prepare response
464 * pyOCD counterpart is _encode_transfer_data.
465 * Packet format: one byte DAP_index (ignored)
466 * one bytes transfer_count
467 * following by number transfer_count pairs of
468 * one byte request (register)
469 * four byte data (for write request only)
470 */
dap_swdp_transfer(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)471 static uint16_t dap_swdp_transfer(struct dap_context *const ctx,
472 const uint8_t *const request,
473 uint8_t *const response)
474 {
475 uint8_t *rspns_buf;
476 const uint8_t *req_buf;
477 uint8_t rspns_cnt = 0;
478 uint8_t rspns_val = 0;
479 bool post_read = false;
480 uint32_t check_write = 0;
481 uint8_t req_cnt;
482 uint8_t req_val;
483 uint32_t match_val;
484 uint32_t data;
485
486 /* Ignore DAP index request[0] */
487 req_cnt = request[1];
488 req_buf = request + sizeof(req_cnt) + 1;
489 rspns_buf = response + (sizeof(rspns_cnt) + sizeof(rspns_val));
490
491 for (; req_cnt; req_cnt--) {
492 req_val = *req_buf++;
493 if (req_val & SWDP_REQUEST_RnW) {
494 /* Read register */
495 if (post_read) {
496 /*
497 * Read was posted before, read previous AP
498 * data or post next AP read.
499 */
500 if ((req_val & (SWDP_REQUEST_APnDP |
501 DAP_TRANSFER_MATCH_VALUE)) !=
502 SWDP_REQUEST_APnDP) {
503 req_val = DP_RDBUFF | SWDP_REQUEST_RnW;
504 post_read = false;
505 }
506
507 rspns_val = do_swdp_transfer(ctx, req_val, &data);
508 if (rspns_val != SWDP_ACK_OK) {
509 break;
510 }
511
512 /* Store previous AP data */
513 sys_put_le32(data, rspns_buf);
514 rspns_buf += sizeof(data);
515 }
516 if (req_val & DAP_TRANSFER_MATCH_VALUE) {
517 LOG_INF("match value read");
518 /* Read with value match */
519 match_val = sys_get_le32(req_buf);
520 req_buf += sizeof(match_val);
521
522 rspns_val = swdp_transfer_match(ctx, req_val, match_val);
523 if (rspns_val != SWDP_ACK_OK) {
524 break;
525 }
526
527 } else if (req_val & SWDP_REQUEST_APnDP) {
528 /* Normal read */
529 if (!post_read) {
530 /* Post AP read */
531 rspns_val = do_swdp_transfer(ctx, req_val, NULL);
532 if (rspns_val != SWDP_ACK_OK) {
533 break;
534 }
535 post_read = true;
536 }
537 } else {
538 /* Read DP register */
539 rspns_val = do_swdp_transfer(ctx, req_val, &data);
540 if (rspns_val != SWDP_ACK_OK) {
541 break;
542 }
543 /* Store data */
544 sys_put_le32(data, rspns_buf);
545 rspns_buf += sizeof(data);
546 }
547 check_write = 0U;
548 } else {
549 /* Write register */
550 if (post_read) {
551 /* Read previous data */
552 rspns_val = do_swdp_transfer(ctx,
553 DP_RDBUFF | SWDP_REQUEST_RnW,
554 &data);
555 if (rspns_val != SWDP_ACK_OK) {
556 break;
557 }
558
559 /* Store previous data */
560 sys_put_le32(data, rspns_buf);
561 rspns_buf += sizeof(data);
562 post_read = false;
563 }
564 /* Load data */
565 data = sys_get_le32(req_buf);
566 req_buf += sizeof(data);
567 if (req_val & DAP_TRANSFER_MATCH_MASK) {
568 /* Write match mask */
569 ctx->transfer.match_mask = data;
570 rspns_val = SWDP_ACK_OK;
571 } else {
572 /* Write DP/AP register */
573 rspns_val = do_swdp_transfer(ctx, req_val, &data);
574 if (rspns_val != SWDP_ACK_OK) {
575 break;
576 }
577
578 check_write = 1U;
579 }
580 }
581 rspns_cnt++;
582 }
583
584 if (rspns_val == SWDP_ACK_OK) {
585 if (post_read) {
586 /* Read previous data */
587 rspns_val = do_swdp_transfer(ctx,
588 DP_RDBUFF | SWDP_REQUEST_RnW,
589 &data);
590 if (rspns_val != SWDP_ACK_OK) {
591 goto end;
592 }
593
594 /* Store previous data */
595 sys_put_le32(data, rspns_buf);
596 rspns_buf += sizeof(data);
597 } else if (check_write) {
598 /* Check last write */
599 rspns_val = do_swdp_transfer(ctx,
600 DP_RDBUFF | SWDP_REQUEST_RnW,
601 NULL);
602 }
603 }
604
605 end:
606 response[0] = rspns_cnt;
607 response[1] = rspns_val;
608
609 return (rspns_buf - response);
610 }
611
612 /* Delegate DAP Transfer command */
dap_transfer(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)613 static uint16_t dap_transfer(struct dap_context *const ctx,
614 const uint8_t *const request,
615 uint8_t *const response)
616 {
617 uint16_t retval;
618
619 if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
620 LOG_ERR("DAP device is not connected");
621 response[0] = DAP_ERROR;
622 return 1U;
623 }
624
625 switch (ctx->debug_port) {
626 case DAP_PORT_SWD:
627 retval = dap_swdp_transfer(ctx, request, response);
628 break;
629 case DAP_PORT_JTAG:
630 default:
631 LOG_ERR("port unsupported");
632 response[0] = DAP_ERROR;
633 retval = 1U;
634 }
635
636 return retval;
637 }
638
dap_swdp_sequence(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)639 static uint16_t dap_swdp_sequence(struct dap_context *const ctx,
640 const uint8_t *const request,
641 uint8_t *const response)
642 {
643 const struct swdp_api *api = ctx->swdp_dev->api;
644 const uint8_t *request_data = request + 1;
645 uint8_t *response_data = response + 1;
646 uint8_t count = request[0];
647 uint8_t num_cycles;
648 uint32_t num_bytes;
649 bool input;
650
651 switch (ctx->debug_port) {
652 case DAP_PORT_SWD:
653 response[0] = DAP_OK;
654 break;
655 case DAP_PORT_JTAG:
656 default:
657 LOG_ERR("port unsupported");
658 response[0] = DAP_ERROR;
659 return 1U;
660 }
661
662 for (size_t i = 0; i < count; ++i) {
663 input = *request_data & BIT(7);
664 num_cycles = *request_data & BIT_MASK(7);
665 num_bytes = (num_cycles + 7) >> 3; /* rounded up to full bytes */
666
667 if (num_cycles == 0) {
668 num_cycles = 64;
669 }
670
671 request_data += 1;
672
673 if (input) {
674 api->swdp_input_sequence(ctx->swdp_dev, num_cycles, response_data);
675 response_data += num_bytes;
676 } else {
677 api->swdp_output_sequence(ctx->swdp_dev, num_cycles, request_data);
678 request_data += num_bytes;
679 }
680 }
681
682 return response_data - response;
683 }
684
685 /*
686 * Process SWD DAP_TransferBlock command and prepare response.
687 * pyOCD counterpart is _encode_transfer_block_data.
688 * Packet format: one byte DAP_index (ignored)
689 * two bytes transfer_count
690 * one byte block_request (register)
691 * data[transfer_count * sizeof(uint32_t)]
692 */
dap_swdp_transferblock(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)693 static uint16_t dap_swdp_transferblock(struct dap_context *const ctx,
694 const uint8_t *const request,
695 uint8_t *const response)
696 {
697 uint32_t data;
698 uint8_t *rspns_buf;
699 const uint8_t *req_buf;
700 uint16_t rspns_cnt = 0;
701 uint16_t req_cnt;
702 uint8_t rspns_val = 0;
703 uint8_t req_val;
704
705 req_cnt = sys_get_le16(&request[1]);
706 req_val = request[3];
707 req_buf = request + (sizeof(req_cnt) + sizeof(req_val) + 1);
708 rspns_buf = response + (sizeof(rspns_cnt) + sizeof(rspns_val));
709
710 if (req_cnt == 0U) {
711 goto end;
712 }
713
714 if (req_val & SWDP_REQUEST_RnW) {
715 /* Read register block */
716 if (req_val & SWDP_REQUEST_APnDP) {
717 /* Post AP read */
718 rspns_val = do_swdp_transfer(ctx, req_val, NULL);
719 if (rspns_val != SWDP_ACK_OK) {
720 goto end;
721 }
722 }
723
724 while (req_cnt--) {
725 /* Read DP/AP register */
726 if ((req_cnt == 0U) &&
727 (req_val & SWDP_REQUEST_APnDP)) {
728 /* Last AP read */
729 req_val = DP_RDBUFF | SWDP_REQUEST_RnW;
730 }
731
732 rspns_val = do_swdp_transfer(ctx, req_val, &data);
733 if (rspns_val != SWDP_ACK_OK) {
734 goto end;
735 }
736
737 /* Store data */
738 sys_put_le32(data, rspns_buf);
739 rspns_buf += sizeof(data);
740 rspns_cnt++;
741 }
742 } else {
743 /* Write register block */
744 while (req_cnt--) {
745 /* Load data */
746 data = sys_get_le32(req_buf);
747 req_buf += sizeof(data);
748 /* Write DP/AP register */
749 rspns_val = do_swdp_transfer(ctx, req_val, &data);
750 if (rspns_val != SWDP_ACK_OK) {
751 goto end;
752 }
753
754 rspns_cnt++;
755 }
756 /* Check last write */
757 rspns_val = do_swdp_transfer(ctx, DP_RDBUFF | SWDP_REQUEST_RnW, NULL);
758 }
759
760 end:
761 sys_put_le16(rspns_cnt, &response[0]);
762 response[2] = rspns_val;
763
764 LOG_DBG("Received %u, to transmit %u, response count %u",
765 req_buf - request,
766 rspns_buf - response,
767 rspns_cnt * 4);
768
769 return (rspns_buf - response);
770 }
771
772 /* Delegate Transfer Block command */
dap_transferblock(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)773 static uint16_t dap_transferblock(struct dap_context *const ctx,
774 const uint8_t *const request,
775 uint8_t *const response)
776 {
777 uint16_t retval;
778
779 if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
780 LOG_ERR("DAP device is not connected");
781 /* Clear response count */
782 sys_put_le16(0U, &response[0]);
783 /* Clear DAP response (ACK) value */
784 response[2] = 0U;
785 return 3U;
786 }
787
788 switch (ctx->debug_port) {
789 case DAP_PORT_SWD:
790 retval = dap_swdp_transferblock(ctx, request, response);
791 break;
792 case DAP_PORT_JTAG:
793 default:
794 LOG_ERR("port unsupported");
795 /* Clear response count */
796 sys_put_le16(0U, &response[0]);
797 /* Clear DAP response (ACK) value */
798 response[2] = 0U;
799 retval = 3U;
800 }
801
802 return retval;
803 }
804
805 /* Process SWD Write ABORT command and prepare response */
dap_swdp_writeabort(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)806 static uint16_t dap_swdp_writeabort(struct dap_context *const ctx,
807 const uint8_t *const request,
808 uint8_t *const response)
809 {
810 const struct swdp_api *api = ctx->swdp_dev->api;
811 /* Load data (Ignore DAP index in request[0]) */
812 uint32_t data = sys_get_le32(&request[1]);
813
814 /* Write Abort register */
815 api->swdp_transfer(ctx->swdp_dev, DP_ABORT, &data,
816 ctx->transfer.idle_cycles, NULL);
817
818 response[0] = DAP_OK;
819 return 1U;
820 }
821
822 /* Delegate DAP Write ABORT command */
dap_writeabort(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)823 static uint16_t dap_writeabort(struct dap_context *const ctx,
824 const uint8_t *const request,
825 uint8_t *const response)
826 {
827 uint16_t retval;
828
829 if (!atomic_test_bit(&ctx->state, DAP_STATE_CONNECTED)) {
830 LOG_ERR("DAP device is not connected");
831 response[0] = DAP_ERROR;
832 return 1U;
833 }
834
835 switch (ctx->debug_port) {
836 case DAP_PORT_SWD:
837 retval = dap_swdp_writeabort(ctx, request, response);
838 break;
839 case DAP_PORT_JTAG:
840 default:
841 LOG_ERR("port unsupported");
842 response[0] = DAP_ERROR;
843 retval = 1U;
844 }
845 return retval;
846 }
847
848 /* Process DAP Vendor command request */
dap_process_vendor_cmd(struct dap_context * const ctx,const uint8_t * const request,uint8_t * const response)849 static uint16_t dap_process_vendor_cmd(struct dap_context *const ctx,
850 const uint8_t *const request,
851 uint8_t *const response)
852 {
853 response[0] = ID_DAP_INVALID;
854 return 1U;
855 }
856
857 /*
858 * Process DAP command request and prepare response
859 * request: pointer to request data
860 * response: pointer to response data
861 * return: number of bytes in response
862 *
863 * All the subsequent command functions have the same parameter
864 * and return value structure.
865 */
dap_process_cmd(struct dap_context * const ctx,const uint8_t * request,uint8_t * response)866 static uint16_t dap_process_cmd(struct dap_context *const ctx,
867 const uint8_t *request,
868 uint8_t *response)
869 {
870 uint16_t retval;
871
872 LOG_HEXDUMP_DBG(request, 8, "req");
873
874 if ((*request >= ID_DAP_VENDOR0) && (*request <= ID_DAP_VENDOR31)) {
875 return dap_process_vendor_cmd(ctx, request, response);
876 }
877
878 *response++ = *request;
879 LOG_DBG("request 0x%02x", *request);
880
881 switch (*request++) {
882 case ID_DAP_INFO:
883 retval = dap_info(ctx, request, response);
884 break;
885 case ID_DAP_HOST_STATUS:
886 retval = dap_host_status(ctx, request, response);
887 break;
888 case ID_DAP_CONNECT:
889 retval = dap_connect(ctx, request, response);
890 break;
891 case ID_DAP_DISCONNECT:
892 retval = dap_disconnect(ctx, response);
893 break;
894 case ID_DAP_DELAY:
895 retval = dap_delay(ctx, request, response);
896 break;
897 case ID_DAP_RESET_TARGET:
898 retval = dap_reset_target(ctx, response);
899 break;
900 case ID_DAP_SWJ_PINS:
901 retval = dap_swj_pins(ctx, request, response);
902 break;
903 case ID_DAP_SWJ_CLOCK:
904 retval = dap_swj_clock(ctx, request, response);
905 break;
906 case ID_DAP_SWJ_SEQUENCE:
907 retval = dap_swj_sequence(ctx, request, response);
908 break;
909 case ID_DAP_SWDP_CONFIGURE:
910 retval = dap_swdp_configure(ctx, request, response);
911 break;
912 case ID_DAP_SWDP_SEQUENCE:
913 retval = dap_swdp_sequence(ctx, request, response);
914 break;
915 case ID_DAP_JTAG_SEQUENCE:
916 LOG_ERR("JTAG sequence unsupported");
917 retval = 1;
918 *response = DAP_ERROR;
919 break;
920 case ID_DAP_JTAG_CONFIGURE:
921 LOG_ERR("JTAG configure unsupported");
922 retval = 1;
923 *response = DAP_ERROR;
924 break;
925 case ID_DAP_JTAG_IDCODE:
926 LOG_ERR("JTAG IDCODE unsupported");
927 retval = 1;
928 *response = DAP_ERROR;
929 break;
930 case ID_DAP_TRANSFER_CONFIGURE:
931 retval = dap_transfer_cfg(ctx, request, response);
932 break;
933 case ID_DAP_TRANSFER:
934 retval = dap_transfer(ctx, request, response);
935 break;
936 case ID_DAP_TRANSFER_BLOCK:
937 retval = dap_transferblock(ctx, request, response);
938 break;
939 case ID_DAP_WRITE_ABORT:
940 retval = dap_writeabort(ctx, request, response);
941 break;
942 case ID_DAP_SWO_TRANSPORT:
943 LOG_ERR("SWO Transport unsupported");
944 retval = 1;
945 *response = DAP_ERROR;
946 break;
947 case ID_DAP_SWO_MODE:
948 LOG_ERR("SWO Mode unsupported");
949 retval = 1;
950 *response = DAP_ERROR;
951 break;
952 case ID_DAP_SWO_BAUDRATE:
953 LOG_ERR("SWO Baudrate unsupported");
954 retval = 1;
955 *response = DAP_ERROR;
956 break;
957 case ID_DAP_SWO_CONTROL:
958 LOG_ERR("SWO Control unsupported");
959 retval = 1;
960 *response = DAP_ERROR;
961 break;
962 case ID_DAP_SWO_STATUS:
963 LOG_ERR("SWO Status unsupported");
964 retval = 1;
965 *response = DAP_ERROR;
966 break;
967 case ID_DAP_SWO_DATA:
968 LOG_ERR("SWO Data unsupported");
969 retval = 1;
970 *response = DAP_ERROR;
971 break;
972 case ID_DAP_UART_TRANSPORT:
973 LOG_ERR("UART Transport unsupported");
974 retval = 1;
975 *response = DAP_ERROR;
976 break;
977 case ID_DAP_UART_CONFIGURE:
978 LOG_ERR("UART Configure unsupported");
979 retval = 1;
980 *response = DAP_ERROR;
981 break;
982 case ID_DAP_UART_CONTROL:
983 LOG_ERR("UART Control unsupported");
984 retval = 1;
985 *response = DAP_ERROR;
986 break;
987 case ID_DAP_UART_STATUS:
988 LOG_ERR("UART Status unsupported");
989 retval = 1;
990 *response = DAP_ERROR;
991 break;
992 case ID_DAP_UART_TRANSFER:
993 LOG_ERR("UART Transfer unsupported");
994 retval = 1;
995 *response = DAP_ERROR;
996 break;
997
998 default:
999 *(response - 1) = ID_DAP_INVALID;
1000 return 1U;
1001 }
1002
1003 return (1U + retval);
1004 }
1005
1006 /*
1007 * Execute DAP command (process request and prepare response)
1008 * request: pointer to request data
1009 * response: pointer to response data
1010 * return: number of bytes in response
1011 */
dap_execute_cmd(const uint8_t * request,uint8_t * response)1012 uint32_t dap_execute_cmd(const uint8_t *request,
1013 uint8_t *response)
1014 {
1015 uint32_t retval;
1016 uint16_t n;
1017 uint8_t count;
1018
1019 if (request[0] == ID_DAP_EXECUTE_COMMANDS) {
1020 /* copy command and increment */
1021 *response++ = *request++;
1022 count = request[0];
1023 request += sizeof(count);
1024 response[0] = count;
1025 response += sizeof(count);
1026 retval = sizeof(count) + 1U;
1027 LOG_WRN("(untested) ID DAP EXECUTE_COMMANDS count %u", count);
1028 while (count--) {
1029 n = dap_process_cmd(&dap_ctx[0], request, response);
1030 retval += n;
1031 request += n;
1032 response += n;
1033 }
1034 return retval;
1035 }
1036
1037 return dap_process_cmd(&dap_ctx[0], request, response);
1038 }
1039
dap_setup(const struct device * const dev)1040 int dap_setup(const struct device *const dev)
1041 {
1042 dap_ctx[0].swdp_dev = (void *)dev;
1043
1044 if (!device_is_ready(dap_ctx[0].swdp_dev)) {
1045 LOG_ERR("SWD driver not ready");
1046 return -ENODEV;
1047 }
1048
1049 /* Default settings */
1050 dap_ctx[0].pkt_size = CONFIG_CMSIS_DAP_PACKET_SIZE;
1051 dap_ctx[0].debug_port = 0U;
1052 dap_ctx[0].transfer.idle_cycles = 0U;
1053 dap_ctx[0].transfer.retry_count = 100U;
1054 dap_ctx[0].transfer.match_retry = 0U;
1055 dap_ctx[0].transfer.match_mask = 0U;
1056 dap_ctx[0].capabilities = DAP_SUPPORTS_ATOMIC_COMMANDS |
1057 DAP_DP_SUPPORTS_SWD;
1058
1059 return 0;
1060 }
1061