source: trunk/firmware_v5/CubeMX/Drivers/CMSIS/DAP/Firmware/Source/DAP.c

Last change on this file was 42, checked in by f.jahn, 5 days ago
File size: 51.9 KB
Line 
1/*
2 * Copyright (c) 2013-2022 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: 26. April 2022
21 * $Revision: V2.1.1
22 *
23 * Project: CMSIS-DAP Source
24 * Title: DAP.c CMSIS-DAP Commands
25 *
26 *---------------------------------------------------------------------------*/
27
28#include <string.h>
29#include "DAP_config.h"
30#include "DAP.h"
31
32
33#if (DAP_PACKET_SIZE < 64U)
34#error "Minimum Packet Size is 64!"
35#endif
36#if (DAP_PACKET_SIZE > 32768U)
37#error "Maximum Packet Size is 32768!"
38#endif
39#if (DAP_PACKET_COUNT < 1U)
40#error "Minimum Packet Count is 1!"
41#endif
42#if (DAP_PACKET_COUNT > 255U)
43#error "Maximum Packet Count is 255!"
44#endif
45
46
47// Clock Macros
48#define MAX_SWJ_CLOCK(delay_cycles) \
49 ((CPU_CLOCK/2U) / (IO_PORT_WRITE_CYCLES + delay_cycles))
50
51
52 DAP_Data_t DAP_Data; // DAP Data
53volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag
54
55
56static const char DAP_FW_Ver [] = DAP_FW_VER;
57
58
59// Common clock delay calculation routine
60// clock: requested SWJ frequency in Hertz
61static void Set_Clock_Delay(uint32_t clock) {
62 uint32_t delay;
63
64 if (clock >= MAX_SWJ_CLOCK(DELAY_FAST_CYCLES)) {
65 DAP_Data.fast_clock = 1U;
66 DAP_Data.clock_delay = 1U;
67 } else {
68 DAP_Data.fast_clock = 0U;
69
70 delay = ((CPU_CLOCK/2U) + (clock - 1U)) / clock;
71 if (delay > IO_PORT_WRITE_CYCLES) {
72 delay -= IO_PORT_WRITE_CYCLES;
73 delay = (delay + (DELAY_SLOW_CYCLES - 1U)) / DELAY_SLOW_CYCLES;
74 } else {
75 delay = 1U;
76 }
77
78 DAP_Data.clock_delay = delay;
79 }
80}
81
82
83// Get DAP Information
84// id: info identifier
85// info: pointer to info data
86// return: number of bytes in info data
87static uint8_t DAP_Info(uint8_t id, uint8_t *info) {
88 uint8_t length = 0U;
89
90 switch (id) {
91 case DAP_ID_VENDOR:
92 length = DAP_GetVendorString((char *)info);
93 break;
94 case DAP_ID_PRODUCT:
95 length = DAP_GetProductString((char *)info);
96 break;
97 case DAP_ID_SER_NUM:
98 length = DAP_GetSerNumString((char *)info);
99 break;
100 case DAP_ID_DAP_FW_VER:
101 length = (uint8_t)sizeof(DAP_FW_Ver);
102 memcpy(info, DAP_FW_Ver, length);
103 break;
104 case DAP_ID_DEVICE_VENDOR:
105 length = DAP_GetTargetDeviceVendorString((char *)info);
106 break;
107 case DAP_ID_DEVICE_NAME:
108 length = DAP_GetTargetDeviceNameString((char *)info);
109 break;
110 case DAP_ID_BOARD_VENDOR:
111 length = DAP_GetTargetBoardVendorString((char *)info);
112 break;
113 case DAP_ID_BOARD_NAME:
114 length = DAP_GetTargetBoardNameString((char *)info);
115 break;
116 case DAP_ID_PRODUCT_FW_VER:
117 length = DAP_GetProductFirmwareVersionString((char *)info);
118 break;
119 case DAP_ID_CAPABILITIES:
120 info[0] = ((DAP_SWD != 0) ? (1U << 0) : 0U) |
121 ((DAP_JTAG != 0) ? (1U << 1) : 0U) |
122 ((SWO_UART != 0) ? (1U << 2) : 0U) |
123 ((SWO_MANCHESTER != 0) ? (1U << 3) : 0U) |
124 /* Atomic Commands */ (1U << 4) |
125 ((TIMESTAMP_CLOCK != 0U) ? (1U << 5) : 0U) |
126 ((SWO_STREAM != 0U) ? (1U << 6) : 0U) |
127 ((DAP_UART != 0U) ? (1U << 7) : 0U);
128
129 info[1] = ((DAP_UART_USB_COM_PORT != 0) ? (1U << 0) : 0U);
130 length = 2U;
131 break;
132 case DAP_ID_TIMESTAMP_CLOCK:
133#if (TIMESTAMP_CLOCK != 0U)
134 info[0] = (uint8_t)(TIMESTAMP_CLOCK >> 0);
135 info[1] = (uint8_t)(TIMESTAMP_CLOCK >> 8);
136 info[2] = (uint8_t)(TIMESTAMP_CLOCK >> 16);
137 info[3] = (uint8_t)(TIMESTAMP_CLOCK >> 24);
138 length = 4U;
139#endif
140 break;
141 case DAP_ID_UART_RX_BUFFER_SIZE:
142#if (DAP_UART != 0)
143 info[0] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 0);
144 info[1] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 8);
145 info[2] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 16);
146 info[3] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 24);
147 length = 4U;
148#endif
149 break;
150 case DAP_ID_UART_TX_BUFFER_SIZE:
151#if (DAP_UART != 0)
152 info[0] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 0);
153 info[1] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 8);
154 info[2] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 16);
155 info[3] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 24);
156 length = 4U;
157#endif
158 break;
159 case DAP_ID_SWO_BUFFER_SIZE:
160#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
161 info[0] = (uint8_t)(SWO_BUFFER_SIZE >> 0);
162 info[1] = (uint8_t)(SWO_BUFFER_SIZE >> 8);
163 info[2] = (uint8_t)(SWO_BUFFER_SIZE >> 16);
164 info[3] = (uint8_t)(SWO_BUFFER_SIZE >> 24);
165 length = 4U;
166#endif
167 break;
168 case DAP_ID_PACKET_SIZE:
169 info[0] = (uint8_t)(DAP_PACKET_SIZE >> 0);
170 info[1] = (uint8_t)(DAP_PACKET_SIZE >> 8);
171 length = 2U;
172 break;
173 case DAP_ID_PACKET_COUNT:
174 info[0] = DAP_PACKET_COUNT;
175 length = 1U;
176 break;
177 default:
178 break;
179 }
180
181 return (length);
182}
183
184
185// Delay for specified time
186// delay: delay time in ms
187void Delayms(uint32_t delay) {
188 delay *= ((CPU_CLOCK/1000U) + (DELAY_SLOW_CYCLES-1U)) / DELAY_SLOW_CYCLES;
189 PIN_DELAY_SLOW(delay);
190}
191
192
193// Process Delay command and prepare response
194// request: pointer to request data
195// response: pointer to response data
196// return: number of bytes in response (lower 16 bits)
197// number of bytes in request (upper 16 bits)
198static uint32_t DAP_Delay(const uint8_t *request, uint8_t *response) {
199 uint32_t delay;
200
201 delay = (uint32_t)(*(request+0)) |
202 (uint32_t)(*(request+1) << 8);
203 delay *= ((CPU_CLOCK/1000000U) + (DELAY_SLOW_CYCLES-1U)) / DELAY_SLOW_CYCLES;
204
205 PIN_DELAY_SLOW(delay);
206
207 *response = DAP_OK;
208 return ((2U << 16) | 1U);
209}
210
211
212// Process Host Status command and prepare response
213// request: pointer to request data
214// response: pointer to response data
215// return: number of bytes in response (lower 16 bits)
216// number of bytes in request (upper 16 bits)
217static uint32_t DAP_HostStatus(const uint8_t *request, uint8_t *response) {
218
219 switch (*request) {
220 case DAP_DEBUGGER_CONNECTED:
221 LED_CONNECTED_OUT((*(request+1) & 1U));
222 break;
223 case DAP_TARGET_RUNNING:
224 LED_RUNNING_OUT((*(request+1) & 1U));
225 break;
226 default:
227 *response = DAP_ERROR;
228 return ((2U << 16) | 1U);
229 }
230
231 *response = DAP_OK;
232 return ((2U << 16) | 1U);
233}
234
235
236// Process Connect command and prepare response
237// request: pointer to request data
238// response: pointer to response data
239// return: number of bytes in response (lower 16 bits)
240// number of bytes in request (upper 16 bits)
241static uint32_t DAP_Connect(const uint8_t *request, uint8_t *response) {
242 uint32_t port;
243
244 if (*request == DAP_PORT_AUTODETECT) {
245 port = DAP_DEFAULT_PORT;
246 } else {
247 port = *request;
248 }
249
250 switch (port) {
251#if (DAP_SWD != 0)
252 case DAP_PORT_SWD:
253 DAP_Data.debug_port = DAP_PORT_SWD;
254 PORT_SWD_SETUP();
255 break;
256#endif
257#if (DAP_JTAG != 0)
258 case DAP_PORT_JTAG:
259 DAP_Data.debug_port = DAP_PORT_JTAG;
260 PORT_JTAG_SETUP();
261 break;
262#endif
263 default:
264 port = DAP_PORT_DISABLED;
265 break;
266 }
267
268 *response = (uint8_t)port;
269 return ((1U << 16) | 1U);
270}
271
272
273// Process Disconnect command and prepare response
274// response: pointer to response data
275// return: number of bytes in response
276static uint32_t DAP_Disconnect(uint8_t *response) {
277
278 DAP_Data.debug_port = DAP_PORT_DISABLED;
279 PORT_OFF();
280
281 *response = DAP_OK;
282 return (1U);
283}
284
285
286// Process Reset Target command and prepare response
287// response: pointer to response data
288// return: number of bytes in response
289static uint32_t DAP_ResetTarget(uint8_t *response) {
290
291 *(response+1) = RESET_TARGET();
292 *(response+0) = DAP_OK;
293 return (2U);
294}
295
296
297// Process SWJ Pins command and prepare response
298// request: pointer to request data
299// response: pointer to response data
300// return: number of bytes in response (lower 16 bits)
301// number of bytes in request (upper 16 bits)
302static uint32_t DAP_SWJ_Pins(const uint8_t *request, uint8_t *response) {
303#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
304 uint32_t value;
305 uint32_t select;
306 uint32_t wait;
307 uint32_t timestamp;
308
309 value = (uint32_t) *(request+0);
310 select = (uint32_t) *(request+1);
311 wait = (uint32_t)(*(request+2) << 0) |
312 (uint32_t)(*(request+3) << 8) |
313 (uint32_t)(*(request+4) << 16) |
314 (uint32_t)(*(request+5) << 24);
315
316 if ((select & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) {
317 if ((value & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) {
318 PIN_SWCLK_TCK_SET();
319 } else {
320 PIN_SWCLK_TCK_CLR();
321 }
322 }
323 if ((select & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) {
324 if ((value & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) {
325 PIN_SWDIO_TMS_SET();
326 } else {
327 PIN_SWDIO_TMS_CLR();
328 }
329 }
330 if ((select & (1U << DAP_SWJ_TDI)) != 0U) {
331 PIN_TDI_OUT(value >> DAP_SWJ_TDI);
332 }
333 if ((select & (1U << DAP_SWJ_nTRST)) != 0U) {
334 PIN_nTRST_OUT(value >> DAP_SWJ_nTRST);
335 }
336 if ((select & (1U << DAP_SWJ_nRESET)) != 0U){
337 PIN_nRESET_OUT(value >> DAP_SWJ_nRESET);
338 }
339
340 if (wait != 0U) {
341#if (TIMESTAMP_CLOCK != 0U)
342 if (wait > 3000000U) {
343 wait = 3000000U;
344 }
345#if (TIMESTAMP_CLOCK >= 1000000U)
346 wait *= TIMESTAMP_CLOCK / 1000000U;
347#else
348 wait /= 1000000U / TIMESTAMP_CLOCK;
349#endif
350#else
351 wait = 1U;
352#endif
353 timestamp = TIMESTAMP_GET();
354 do {
355 if ((select & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) {
356 if ((value >> DAP_SWJ_SWCLK_TCK) ^ PIN_SWCLK_TCK_IN()) {
357 continue;
358 }
359 }
360 if ((select & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) {
361 if ((value >> DAP_SWJ_SWDIO_TMS) ^ PIN_SWDIO_TMS_IN()) {
362 continue;
363 }
364 }
365 if ((select & (1U << DAP_SWJ_TDI)) != 0U) {
366 if ((value >> DAP_SWJ_TDI) ^ PIN_TDI_IN()) {
367 continue;
368 }
369 }
370 if ((select & (1U << DAP_SWJ_nTRST)) != 0U) {
371 if ((value >> DAP_SWJ_nTRST) ^ PIN_nTRST_IN()) {
372 continue;
373 }
374 }
375 if ((select & (1U << DAP_SWJ_nRESET)) != 0U) {
376 if ((value >> DAP_SWJ_nRESET) ^ PIN_nRESET_IN()) {
377 continue;
378 }
379 }
380 break;
381 } while ((TIMESTAMP_GET() - timestamp) < wait);
382 }
383
384 value = (PIN_SWCLK_TCK_IN() << DAP_SWJ_SWCLK_TCK) |
385 (PIN_SWDIO_TMS_IN() << DAP_SWJ_SWDIO_TMS) |
386 (PIN_TDI_IN() << DAP_SWJ_TDI) |
387 (PIN_TDO_IN() << DAP_SWJ_TDO) |
388 (PIN_nTRST_IN() << DAP_SWJ_nTRST) |
389 (PIN_nRESET_IN() << DAP_SWJ_nRESET);
390
391 *response = (uint8_t)value;
392#else
393 *response = 0U;
394#endif
395
396 return ((6U << 16) | 1U);
397}
398
399
400// Process SWJ Clock command and prepare response
401// request: pointer to request data
402// response: pointer to response data
403// return: number of bytes in response (lower 16 bits)
404// number of bytes in request (upper 16 bits)
405static uint32_t DAP_SWJ_Clock(const uint8_t *request, uint8_t *response) {
406#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
407 uint32_t clock;
408 uint32_t delay;
409
410 clock = (uint32_t)(*(request+0) << 0) |
411 (uint32_t)(*(request+1) << 8) |
412 (uint32_t)(*(request+2) << 16) |
413 (uint32_t)(*(request+3) << 24);
414
415 if (clock == 0U) {
416 *response = DAP_ERROR;
417 return ((4U << 16) | 1U);
418 }
419
420 Set_Clock_Delay(clock);
421
422 *response = DAP_OK;
423#else
424 *response = DAP_ERROR;
425#endif
426
427 return ((4U << 16) | 1U);
428}
429
430
431// Process SWJ Sequence command and prepare response
432// request: pointer to request data
433// response: pointer to response data
434// return: number of bytes in response (lower 16 bits)
435// number of bytes in request (upper 16 bits)
436static uint32_t DAP_SWJ_Sequence(const uint8_t *request, uint8_t *response) {
437 uint32_t count;
438
439 count = *request++;
440 if (count == 0U) {
441 count = 256U;
442 }
443
444#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
445 SWJ_Sequence(count, request);
446 *response = DAP_OK;
447#else
448 *response = DAP_ERROR;
449#endif
450
451 count = (count + 7U) >> 3;
452
453 return (((count + 1U) << 16) | 1U);
454}
455
456
457// Process SWD Configure command and prepare response
458// request: pointer to request data
459// response: pointer to response data
460// return: number of bytes in response (lower 16 bits)
461// number of bytes in request (upper 16 bits)
462static uint32_t DAP_SWD_Configure(const uint8_t *request, uint8_t *response) {
463#if (DAP_SWD != 0)
464 uint8_t value;
465
466 value = *request;
467 DAP_Data.swd_conf.turnaround = (value & 0x03U) + 1U;
468 DAP_Data.swd_conf.data_phase = (value & 0x04U) ? 1U : 0U;
469
470 *response = DAP_OK;
471#else
472 *response = DAP_ERROR;
473#endif
474
475 return ((1U << 16) | 1U);
476}
477
478
479// Process SWD Sequence command and prepare response
480// request: pointer to request data
481// response: pointer to response data
482// return: number of bytes in response (lower 16 bits)
483// number of bytes in request (upper 16 bits)
484static uint32_t DAP_SWD_Sequence(const uint8_t *request, uint8_t *response) {
485 uint32_t sequence_info;
486 uint32_t sequence_count;
487 uint32_t request_count;
488 uint32_t response_count;
489 uint32_t count;
490
491#if (DAP_SWD != 0)
492 *response++ = DAP_OK;
493#else
494 *response++ = DAP_ERROR;
495#endif
496 request_count = 1U;
497 response_count = 1U;
498
499 sequence_count = *request++;
500 while (sequence_count--) {
501 sequence_info = *request++;
502 count = sequence_info & SWD_SEQUENCE_CLK;
503 if (count == 0U) {
504 count = 64U;
505 }
506 count = (count + 7U) / 8U;
507#if (DAP_SWD != 0)
508 if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) {
509 PIN_SWDIO_OUT_DISABLE();
510 } else {
511 PIN_SWDIO_OUT_ENABLE();
512 }
513 SWD_Sequence(sequence_info, request, response);
514 if (sequence_count == 0U) {
515 PIN_SWDIO_OUT_ENABLE();
516 }
517#endif
518 if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) {
519 request_count++;
520#if (DAP_SWD != 0)
521 response += count;
522 response_count += count;
523#endif
524 } else {
525 request += count;
526 request_count += count + 1U;
527 }
528 }
529
530 return ((request_count << 16) | response_count);
531}
532
533
534// Process JTAG Sequence command and prepare response
535// request: pointer to request data
536// response: pointer to response data
537// return: number of bytes in response (lower 16 bits)
538// number of bytes in request (upper 16 bits)
539static uint32_t DAP_JTAG_Sequence(const uint8_t *request, uint8_t *response) {
540 uint32_t sequence_info;
541 uint32_t sequence_count;
542 uint32_t request_count;
543 uint32_t response_count;
544 uint32_t count;
545
546#if (DAP_JTAG != 0)
547 *response++ = DAP_OK;
548#else
549 *response++ = DAP_ERROR;
550#endif
551 request_count = 1U;
552 response_count = 1U;
553
554 sequence_count = *request++;
555 while (sequence_count--) {
556 sequence_info = *request++;
557 count = sequence_info & JTAG_SEQUENCE_TCK;
558 if (count == 0U) {
559 count = 64U;
560 }
561 count = (count + 7U) / 8U;
562#if (DAP_JTAG != 0)
563 JTAG_Sequence(sequence_info, request, response);
564#endif
565 request += count;
566 request_count += count + 1U;
567#if (DAP_JTAG != 0)
568 if ((sequence_info & JTAG_SEQUENCE_TDO) != 0U) {
569 response += count;
570 response_count += count;
571 }
572#endif
573 }
574
575 return ((request_count << 16) | response_count);
576}
577
578
579// Process JTAG Configure command and prepare response
580// request: pointer to request data
581// response: pointer to response data
582// return: number of bytes in response (lower 16 bits)
583// number of bytes in request (upper 16 bits)
584static uint32_t DAP_JTAG_Configure(const uint8_t *request, uint8_t *response) {
585 uint32_t count;
586#if (DAP_JTAG != 0)
587 uint32_t length;
588 uint32_t bits;
589 uint32_t n;
590
591 count = *request++;
592 DAP_Data.jtag_dev.count = (uint8_t)count;
593
594 bits = 0U;
595 for (n = 0U; n < count; n++) {
596 length = *request++;
597 DAP_Data.jtag_dev.ir_length[n] = (uint8_t)length;
598 DAP_Data.jtag_dev.ir_before[n] = (uint16_t)bits;
599 bits += length;
600 }
601 for (n = 0U; n < count; n++) {
602 bits -= DAP_Data.jtag_dev.ir_length[n];
603 DAP_Data.jtag_dev.ir_after[n] = (uint16_t)bits;
604 }
605
606 *response = DAP_OK;
607#else
608 count = *request;
609 *response = DAP_ERROR;
610#endif
611
612 return (((count + 1U) << 16) | 1U);
613}
614
615
616// Process JTAG IDCODE command and prepare response
617// request: pointer to request data
618// response: pointer to response data
619// return: number of bytes in response (lower 16 bits)
620// number of bytes in request (upper 16 bits)
621static uint32_t DAP_JTAG_IDCode(const uint8_t *request, uint8_t *response) {
622#if (DAP_JTAG != 0)
623 uint32_t data;
624
625 if (DAP_Data.debug_port != DAP_PORT_JTAG) {
626 goto id_error;
627 }
628
629 // Device index (JTAP TAP)
630 DAP_Data.jtag_dev.index = *request;
631 if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
632 goto id_error;
633 }
634
635 // Select JTAG chain
636 JTAG_IR(JTAG_IDCODE);
637
638 // Read IDCODE register
639 data = JTAG_ReadIDCode();
640
641 // Store Data
642 *(response+0) = DAP_OK;
643 *(response+1) = (uint8_t)(data >> 0);
644 *(response+2) = (uint8_t)(data >> 8);
645 *(response+3) = (uint8_t)(data >> 16);
646 *(response+4) = (uint8_t)(data >> 24);
647
648 return ((1U << 16) | 5U);
649
650id_error:
651#endif
652 *response = DAP_ERROR;
653 return ((1U << 16) | 1U);
654}
655
656
657// Process Transfer Configure command and prepare response
658// request: pointer to request data
659// response: pointer to response data
660// return: number of bytes in response (lower 16 bits)
661// number of bytes in request (upper 16 bits)
662static uint32_t DAP_TransferConfigure(const uint8_t *request, uint8_t *response) {
663
664 DAP_Data.transfer.idle_cycles = *(request+0);
665 DAP_Data.transfer.retry_count = (uint16_t) *(request+1) |
666 (uint16_t)(*(request+2) << 8);
667 DAP_Data.transfer.match_retry = (uint16_t) *(request+3) |
668 (uint16_t)(*(request+4) << 8);
669
670 *response = DAP_OK;
671 return ((5U << 16) | 1U);
672}
673
674
675// Process SWD Transfer command and prepare response
676// request: pointer to request data
677// response: pointer to response data
678// return: number of bytes in response (lower 16 bits)
679// number of bytes in request (upper 16 bits)
680#if (DAP_SWD != 0)
681static uint32_t DAP_SWD_Transfer(const uint8_t *request, uint8_t *response) {
682 const
683 uint8_t *request_head;
684 uint32_t request_count;
685 uint32_t request_value;
686 uint8_t *response_head;
687 uint32_t response_count;
688 uint32_t response_value;
689 uint32_t post_read;
690 uint32_t check_write;
691 uint32_t match_value;
692 uint32_t match_retry;
693 uint32_t retry;
694 uint32_t data;
695#if (TIMESTAMP_CLOCK != 0U)
696 uint32_t timestamp;
697#endif
698
699 request_head = request;
700
701 response_count = 0U;
702 response_value = 0U;
703 response_head = response;
704 response += 2;
705
706 DAP_TransferAbort = 0U;
707
708 post_read = 0U;
709 check_write = 0U;
710
711 request++; // Ignore DAP index
712
713 request_count = *request++;
714
715 for (; request_count != 0U; request_count--) {
716 request_value = *request++;
717 if ((request_value & DAP_TRANSFER_RnW) != 0U) {
718 // Read register
719 if (post_read) {
720 // Read was posted before
721 retry = DAP_Data.transfer.retry_count;
722 if ((request_value & (DAP_TRANSFER_APnDP | DAP_TRANSFER_MATCH_VALUE)) == DAP_TRANSFER_APnDP) {
723 // Read previous AP data and post next AP read
724 do {
725 response_value = SWD_Transfer(request_value, &data);
726 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
727 } else {
728 // Read previous AP data
729 do {
730 response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
731 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
732 post_read = 0U;
733 }
734 if (response_value != DAP_TRANSFER_OK) {
735 break;
736 }
737 // Store previous AP data
738 *response++ = (uint8_t) data;
739 *response++ = (uint8_t)(data >> 8);
740 *response++ = (uint8_t)(data >> 16);
741 *response++ = (uint8_t)(data >> 24);
742#if (TIMESTAMP_CLOCK != 0U)
743 if (post_read) {
744 // Store Timestamp of next AP read
745 if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
746 timestamp = DAP_Data.timestamp;
747 *response++ = (uint8_t) timestamp;
748 *response++ = (uint8_t)(timestamp >> 8);
749 *response++ = (uint8_t)(timestamp >> 16);
750 *response++ = (uint8_t)(timestamp >> 24);
751 }
752 }
753#endif
754 }
755 if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
756 // Read with value match
757 match_value = (uint32_t)(*(request+0) << 0) |
758 (uint32_t)(*(request+1) << 8) |
759 (uint32_t)(*(request+2) << 16) |
760 (uint32_t)(*(request+3) << 24);
761 request += 4;
762 match_retry = DAP_Data.transfer.match_retry;
763 if ((request_value & DAP_TRANSFER_APnDP) != 0U) {
764 // Post AP read
765 retry = DAP_Data.transfer.retry_count;
766 do {
767 response_value = SWD_Transfer(request_value, NULL);
768 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
769 if (response_value != DAP_TRANSFER_OK) {
770 break;
771 }
772 }
773 do {
774 // Read register until its value matches or retry counter expires
775 retry = DAP_Data.transfer.retry_count;
776 do {
777 response_value = SWD_Transfer(request_value, &data);
778 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
779 if (response_value != DAP_TRANSFER_OK) {
780 break;
781 }
782 } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort);
783 if ((data & DAP_Data.transfer.match_mask) != match_value) {
784 response_value |= DAP_TRANSFER_MISMATCH;
785 }
786 if (response_value != DAP_TRANSFER_OK) {
787 break;
788 }
789 } else {
790 // Normal read
791 retry = DAP_Data.transfer.retry_count;
792 if ((request_value & DAP_TRANSFER_APnDP) != 0U) {
793 // Read AP register
794 if (post_read == 0U) {
795 // Post AP read
796 do {
797 response_value = SWD_Transfer(request_value, NULL);
798 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
799 if (response_value != DAP_TRANSFER_OK) {
800 break;
801 }
802#if (TIMESTAMP_CLOCK != 0U)
803 // Store Timestamp
804 if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
805 timestamp = DAP_Data.timestamp;
806 *response++ = (uint8_t) timestamp;
807 *response++ = (uint8_t)(timestamp >> 8);
808 *response++ = (uint8_t)(timestamp >> 16);
809 *response++ = (uint8_t)(timestamp >> 24);
810 }
811#endif
812 post_read = 1U;
813 }
814 } else {
815 // Read DP register
816 do {
817 response_value = SWD_Transfer(request_value, &data);
818 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
819 if (response_value != DAP_TRANSFER_OK) {
820 break;
821 }
822#if (TIMESTAMP_CLOCK != 0U)
823 // Store Timestamp
824 if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
825 timestamp = DAP_Data.timestamp;
826 *response++ = (uint8_t) timestamp;
827 *response++ = (uint8_t)(timestamp >> 8);
828 *response++ = (uint8_t)(timestamp >> 16);
829 *response++ = (uint8_t)(timestamp >> 24);
830 }
831#endif
832 // Store data
833 *response++ = (uint8_t) data;
834 *response++ = (uint8_t)(data >> 8);
835 *response++ = (uint8_t)(data >> 16);
836 *response++ = (uint8_t)(data >> 24);
837 }
838 }
839 check_write = 0U;
840 } else {
841 // Write register
842 if (post_read) {
843 // Read previous data
844 retry = DAP_Data.transfer.retry_count;
845 do {
846 response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
847 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
848 if (response_value != DAP_TRANSFER_OK) {
849 break;
850 }
851 // Store previous data
852 *response++ = (uint8_t) data;
853 *response++ = (uint8_t)(data >> 8);
854 *response++ = (uint8_t)(data >> 16);
855 *response++ = (uint8_t)(data >> 24);
856 post_read = 0U;
857 }
858 // Load data
859 data = (uint32_t)(*(request+0) << 0) |
860 (uint32_t)(*(request+1) << 8) |
861 (uint32_t)(*(request+2) << 16) |
862 (uint32_t)(*(request+3) << 24);
863 request += 4;
864 if ((request_value & DAP_TRANSFER_MATCH_MASK) != 0U) {
865 // Write match mask
866 DAP_Data.transfer.match_mask = data;
867 response_value = DAP_TRANSFER_OK;
868 } else {
869 // Write DP/AP register
870 retry = DAP_Data.transfer.retry_count;
871 do {
872 response_value = SWD_Transfer(request_value, &data);
873 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
874 if (response_value != DAP_TRANSFER_OK) {
875 break;
876 }
877#if (TIMESTAMP_CLOCK != 0U)
878 // Store Timestamp
879 if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
880 timestamp = DAP_Data.timestamp;
881 *response++ = (uint8_t) timestamp;
882 *response++ = (uint8_t)(timestamp >> 8);
883 *response++ = (uint8_t)(timestamp >> 16);
884 *response++ = (uint8_t)(timestamp >> 24);
885 }
886#endif
887 check_write = 1U;
888 }
889 }
890 response_count++;
891 if (DAP_TransferAbort) {
892 break;
893 }
894 }
895
896 for (; request_count != 0U; request_count--) {
897 // Process canceled requests
898 request_value = *request++;
899 if ((request_value & DAP_TRANSFER_RnW) != 0U) {
900 // Read register
901 if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
902 // Read with value match
903 request += 4;
904 }
905 } else {
906 // Write register
907 request += 4;
908 }
909 }
910
911 if (response_value == DAP_TRANSFER_OK) {
912 if (post_read) {
913 // Read previous data
914 retry = DAP_Data.transfer.retry_count;
915 do {
916 response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
917 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
918 if (response_value != DAP_TRANSFER_OK) {
919 goto end;
920 }
921 // Store previous data
922 *response++ = (uint8_t) data;
923 *response++ = (uint8_t)(data >> 8);
924 *response++ = (uint8_t)(data >> 16);
925 *response++ = (uint8_t)(data >> 24);
926 } else if (check_write) {
927 // Check last write
928 retry = DAP_Data.transfer.retry_count;
929 do {
930 response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
931 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
932 }
933 }
934
935end:
936 *(response_head+0) = (uint8_t)response_count;
937 *(response_head+1) = (uint8_t)response_value;
938
939 return (((uint32_t)(request - request_head) << 16) | (uint32_t)(response - response_head));
940}
941#endif
942
943
944// Process JTAG Transfer command and prepare response
945// request: pointer to request data
946// response: pointer to response data
947// return: number of bytes in response (lower 16 bits)
948// number of bytes in request (upper 16 bits)
949#if (DAP_JTAG != 0)
950static uint32_t DAP_JTAG_Transfer(const uint8_t *request, uint8_t *response) {
951 const
952 uint8_t *request_head;
953 uint32_t request_count;
954 uint32_t request_value;
955 uint32_t request_ir;
956 uint8_t *response_head;
957 uint32_t response_count;
958 uint32_t response_value;
959 uint32_t post_read;
960 uint32_t match_value;
961 uint32_t match_retry;
962 uint32_t retry;
963 uint32_t data;
964 uint32_t ir;
965#if (TIMESTAMP_CLOCK != 0U)
966 uint32_t timestamp;
967#endif
968
969 request_head = request;
970
971 response_count = 0U;
972 response_value = 0U;
973 response_head = response;
974 response += 2;
975
976 DAP_TransferAbort = 0U;
977
978 ir = 0U;
979 post_read = 0U;
980
981 // Device index (JTAP TAP)
982 DAP_Data.jtag_dev.index = *request++;
983 if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
984 goto end;
985 }
986
987 request_count = *request++;
988
989 for (; request_count != 0U; request_count--) {
990 request_value = *request++;
991 request_ir = (request_value & DAP_TRANSFER_APnDP) ? JTAG_APACC : JTAG_DPACC;
992 if ((request_value & DAP_TRANSFER_RnW) != 0U) {
993 // Read register
994 if (post_read) {
995 // Read was posted before
996 retry = DAP_Data.transfer.retry_count;
997 if ((ir == request_ir) && ((request_value & DAP_TRANSFER_MATCH_VALUE) == 0U)) {
998 // Read previous data and post next read
999 do {
1000 response_value = JTAG_Transfer(request_value, &data);
1001 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1002 } else {
1003 // Select JTAG chain
1004 if (ir != JTAG_DPACC) {
1005 ir = JTAG_DPACC;
1006 JTAG_IR(ir);
1007 }
1008 // Read previous data
1009 do {
1010 response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
1011 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1012 post_read = 0U;
1013 }
1014 if (response_value != DAP_TRANSFER_OK) {
1015 break;
1016 }
1017 // Store previous data
1018 *response++ = (uint8_t) data;
1019 *response++ = (uint8_t)(data >> 8);
1020 *response++ = (uint8_t)(data >> 16);
1021 *response++ = (uint8_t)(data >> 24);
1022#if (TIMESTAMP_CLOCK != 0U)
1023 if (post_read) {
1024 // Store Timestamp of next AP read
1025 if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
1026 timestamp = DAP_Data.timestamp;
1027 *response++ = (uint8_t) timestamp;
1028 *response++ = (uint8_t)(timestamp >> 8);
1029 *response++ = (uint8_t)(timestamp >> 16);
1030 *response++ = (uint8_t)(timestamp >> 24);
1031 }
1032 }
1033#endif
1034 }
1035 if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
1036 // Read with value match
1037 match_value = (uint32_t)(*(request+0) << 0) |
1038 (uint32_t)(*(request+1) << 8) |
1039 (uint32_t)(*(request+2) << 16) |
1040 (uint32_t)(*(request+3) << 24);
1041 request += 4;
1042 match_retry = DAP_Data.transfer.match_retry;
1043 // Select JTAG chain
1044 if (ir != request_ir) {
1045 ir = request_ir;
1046 JTAG_IR(ir);
1047 }
1048 // Post DP/AP read
1049 retry = DAP_Data.transfer.retry_count;
1050 do {
1051 response_value = JTAG_Transfer(request_value, NULL);
1052 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1053 if (response_value != DAP_TRANSFER_OK) {
1054 break;
1055 }
1056 do {
1057 // Read register until its value matches or retry counter expires
1058 retry = DAP_Data.transfer.retry_count;
1059 do {
1060 response_value = JTAG_Transfer(request_value, &data);
1061 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1062 if (response_value != DAP_TRANSFER_OK) {
1063 break;
1064 }
1065 } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort);
1066 if ((data & DAP_Data.transfer.match_mask) != match_value) {
1067 response_value |= DAP_TRANSFER_MISMATCH;
1068 }
1069 if (response_value != DAP_TRANSFER_OK) {
1070 break;
1071 }
1072 } else {
1073 // Normal read
1074 if (post_read == 0U) {
1075 // Select JTAG chain
1076 if (ir != request_ir) {
1077 ir = request_ir;
1078 JTAG_IR(ir);
1079 }
1080 // Post DP/AP read
1081 retry = DAP_Data.transfer.retry_count;
1082 do {
1083 response_value = JTAG_Transfer(request_value, NULL);
1084 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1085 if (response_value != DAP_TRANSFER_OK) {
1086 break;
1087 }
1088#if (TIMESTAMP_CLOCK != 0U)
1089 // Store Timestamp
1090 if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
1091 timestamp = DAP_Data.timestamp;
1092 *response++ = (uint8_t) timestamp;
1093 *response++ = (uint8_t)(timestamp >> 8);
1094 *response++ = (uint8_t)(timestamp >> 16);
1095 *response++ = (uint8_t)(timestamp >> 24);
1096 }
1097#endif
1098 post_read = 1U;
1099 }
1100 }
1101 } else {
1102 // Write register
1103 if (post_read) {
1104 // Select JTAG chain
1105 if (ir != JTAG_DPACC) {
1106 ir = JTAG_DPACC;
1107 JTAG_IR(ir);
1108 }
1109 // Read previous data
1110 retry = DAP_Data.transfer.retry_count;
1111 do {
1112 response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
1113 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1114 if (response_value != DAP_TRANSFER_OK) {
1115 break;
1116 }
1117 // Store previous data
1118 *response++ = (uint8_t) data;
1119 *response++ = (uint8_t)(data >> 8);
1120 *response++ = (uint8_t)(data >> 16);
1121 *response++ = (uint8_t)(data >> 24);
1122 post_read = 0U;
1123 }
1124 // Load data
1125 data = (uint32_t)(*(request+0) << 0) |
1126 (uint32_t)(*(request+1) << 8) |
1127 (uint32_t)(*(request+2) << 16) |
1128 (uint32_t)(*(request+3) << 24);
1129 request += 4;
1130 if ((request_value & DAP_TRANSFER_MATCH_MASK) != 0U) {
1131 // Write match mask
1132 DAP_Data.transfer.match_mask = data;
1133 response_value = DAP_TRANSFER_OK;
1134 } else {
1135 // Select JTAG chain
1136 if (ir != request_ir) {
1137 ir = request_ir;
1138 JTAG_IR(ir);
1139 }
1140 // Write DP/AP register
1141 retry = DAP_Data.transfer.retry_count;
1142 do {
1143 response_value = JTAG_Transfer(request_value, &data);
1144 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1145 if (response_value != DAP_TRANSFER_OK) {
1146 break;
1147 }
1148#if (TIMESTAMP_CLOCK != 0U)
1149 // Store Timestamp
1150 if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
1151 timestamp = DAP_Data.timestamp;
1152 *response++ = (uint8_t) timestamp;
1153 *response++ = (uint8_t)(timestamp >> 8);
1154 *response++ = (uint8_t)(timestamp >> 16);
1155 *response++ = (uint8_t)(timestamp >> 24);
1156 }
1157#endif
1158 }
1159 }
1160 response_count++;
1161 if (DAP_TransferAbort) {
1162 break;
1163 }
1164 }
1165
1166 for (; request_count != 0U; request_count--) {
1167 // Process canceled requests
1168 request_value = *request++;
1169 if ((request_value & DAP_TRANSFER_RnW) != 0U) {
1170 // Read register
1171 if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
1172 // Read with value match
1173 request += 4;
1174 }
1175 } else {
1176 // Write register
1177 request += 4;
1178 }
1179 }
1180
1181 if (response_value == DAP_TRANSFER_OK) {
1182 // Select JTAG chain
1183 if (ir != JTAG_DPACC) {
1184 ir = JTAG_DPACC;
1185 JTAG_IR(ir);
1186 }
1187 if (post_read) {
1188 // Read previous data
1189 retry = DAP_Data.transfer.retry_count;
1190 do {
1191 response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
1192 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1193 if (response_value != DAP_TRANSFER_OK) {
1194 goto end;
1195 }
1196 // Store previous data
1197 *response++ = (uint8_t) data;
1198 *response++ = (uint8_t)(data >> 8);
1199 *response++ = (uint8_t)(data >> 16);
1200 *response++ = (uint8_t)(data >> 24);
1201 } else {
1202 // Check last write
1203 retry = DAP_Data.transfer.retry_count;
1204 do {
1205 response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
1206 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1207 }
1208 }
1209
1210end:
1211 *(response_head+0) = (uint8_t)response_count;
1212 *(response_head+1) = (uint8_t)response_value;
1213
1214 return (((uint32_t)(request - request_head) << 16) | (uint32_t)(response - response_head));
1215}
1216#endif
1217
1218
1219// Process Dummy Transfer command and prepare response
1220// request: pointer to request data
1221// response: pointer to response data
1222// return: number of bytes in response (lower 16 bits)
1223// number of bytes in request (upper 16 bits)
1224static uint32_t DAP_Dummy_Transfer(const uint8_t *request, uint8_t *response) {
1225 const
1226 uint8_t *request_head;
1227 uint32_t request_count;
1228 uint32_t request_value;
1229
1230 request_head = request;
1231
1232 request++; // Ignore DAP index
1233
1234 request_count = *request++;
1235
1236 for (; request_count != 0U; request_count--) {
1237 // Process dummy requests
1238 request_value = *request++;
1239 if ((request_value & DAP_TRANSFER_RnW) != 0U) {
1240 // Read register
1241 if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
1242 // Read with value match
1243 request += 4;
1244 }
1245 } else {
1246 // Write register
1247 request += 4;
1248 }
1249 }
1250
1251 *(response+0) = 0U; // Response count
1252 *(response+1) = 0U; // Response value
1253
1254 return (((uint32_t)(request - request_head) << 16) | 2U);
1255}
1256
1257
1258// Process Transfer command and prepare response
1259// request: pointer to request data
1260// response: pointer to response data
1261// return: number of bytes in response (lower 16 bits)
1262// number of bytes in request (upper 16 bits)
1263static uint32_t DAP_Transfer(const uint8_t *request, uint8_t *response) {
1264 uint32_t num;
1265
1266 switch (DAP_Data.debug_port) {
1267#if (DAP_SWD != 0)
1268 case DAP_PORT_SWD:
1269 num = DAP_SWD_Transfer(request, response);
1270 break;
1271#endif
1272#if (DAP_JTAG != 0)
1273 case DAP_PORT_JTAG:
1274 num = DAP_JTAG_Transfer(request, response);
1275 break;
1276#endif
1277 default:
1278 num = DAP_Dummy_Transfer(request, response);
1279 break;
1280 }
1281
1282 return (num);
1283}
1284
1285
1286// Process SWD Transfer Block command and prepare response
1287// request: pointer to request data
1288// response: pointer to response data
1289// return: number of bytes in response
1290#if (DAP_SWD != 0)
1291static uint32_t DAP_SWD_TransferBlock(const uint8_t *request, uint8_t *response) {
1292 uint32_t request_count;
1293 uint32_t request_value;
1294 uint32_t response_count;
1295 uint32_t response_value;
1296 uint8_t *response_head;
1297 uint32_t retry;
1298 uint32_t data;
1299
1300 response_count = 0U;
1301 response_value = 0U;
1302 response_head = response;
1303 response += 3;
1304
1305 DAP_TransferAbort = 0U;
1306
1307 request++; // Ignore DAP index
1308
1309 request_count = (uint32_t)(*(request+0) << 0) |
1310 (uint32_t)(*(request+1) << 8);
1311 request += 2;
1312 if (request_count == 0U) {
1313 goto end;
1314 }
1315
1316 request_value = *request++;
1317 if ((request_value & DAP_TRANSFER_RnW) != 0U) {
1318 // Read register block
1319 if ((request_value & DAP_TRANSFER_APnDP) != 0U) {
1320 // Post AP read
1321 retry = DAP_Data.transfer.retry_count;
1322 do {
1323 response_value = SWD_Transfer(request_value, NULL);
1324 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1325 if (response_value != DAP_TRANSFER_OK) {
1326 goto end;
1327 }
1328 }
1329 while (request_count--) {
1330 // Read DP/AP register
1331 if ((request_count == 0U) && ((request_value & DAP_TRANSFER_APnDP) != 0U)) {
1332 // Last AP read
1333 request_value = DP_RDBUFF | DAP_TRANSFER_RnW;
1334 }
1335 retry = DAP_Data.transfer.retry_count;
1336 do {
1337 response_value = SWD_Transfer(request_value, &data);
1338 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1339 if (response_value != DAP_TRANSFER_OK) {
1340 goto end;
1341 }
1342 // Store data
1343 *response++ = (uint8_t) data;
1344 *response++ = (uint8_t)(data >> 8);
1345 *response++ = (uint8_t)(data >> 16);
1346 *response++ = (uint8_t)(data >> 24);
1347 response_count++;
1348 }
1349 } else {
1350 // Write register block
1351 while (request_count--) {
1352 // Load data
1353 data = (uint32_t)(*(request+0) << 0) |
1354 (uint32_t)(*(request+1) << 8) |
1355 (uint32_t)(*(request+2) << 16) |
1356 (uint32_t)(*(request+3) << 24);
1357 request += 4;
1358 // Write DP/AP register
1359 retry = DAP_Data.transfer.retry_count;
1360 do {
1361 response_value = SWD_Transfer(request_value, &data);
1362 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1363 if (response_value != DAP_TRANSFER_OK) {
1364 goto end;
1365 }
1366 response_count++;
1367 }
1368 // Check last write
1369 retry = DAP_Data.transfer.retry_count;
1370 do {
1371 response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
1372 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1373 }
1374
1375end:
1376 *(response_head+0) = (uint8_t)(response_count >> 0);
1377 *(response_head+1) = (uint8_t)(response_count >> 8);
1378 *(response_head+2) = (uint8_t) response_value;
1379
1380 return ((uint32_t)(response - response_head));
1381}
1382#endif
1383
1384
1385// Process JTAG Transfer Block command and prepare response
1386// request: pointer to request data
1387// response: pointer to response data
1388// return: number of bytes in response
1389#if (DAP_JTAG != 0)
1390static uint32_t DAP_JTAG_TransferBlock(const uint8_t *request, uint8_t *response) {
1391 uint32_t request_count;
1392 uint32_t request_value;
1393 uint32_t response_count;
1394 uint32_t response_value;
1395 uint8_t *response_head;
1396 uint32_t retry;
1397 uint32_t data;
1398 uint32_t ir;
1399
1400 response_count = 0U;
1401 response_value = 0U;
1402 response_head = response;
1403 response += 3;
1404
1405 DAP_TransferAbort = 0U;
1406
1407 // Device index (JTAP TAP)
1408 DAP_Data.jtag_dev.index = *request++;
1409 if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
1410 goto end;
1411 }
1412
1413 request_count = (uint32_t)(*(request+0) << 0) |
1414 (uint32_t)(*(request+1) << 8);
1415 request += 2;
1416 if (request_count == 0U) {
1417 goto end;
1418 }
1419
1420 request_value = *request++;
1421
1422 // Select JTAG chain
1423 ir = (request_value & DAP_TRANSFER_APnDP) ? JTAG_APACC : JTAG_DPACC;
1424 JTAG_IR(ir);
1425
1426 if ((request_value & DAP_TRANSFER_RnW) != 0U) {
1427 // Post read
1428 retry = DAP_Data.transfer.retry_count;
1429 do {
1430 response_value = JTAG_Transfer(request_value, NULL);
1431 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1432 if (response_value != DAP_TRANSFER_OK) {
1433 goto end;
1434 }
1435 // Read register block
1436 while (request_count--) {
1437 // Read DP/AP register
1438 if (request_count == 0U) {
1439 // Last read
1440 if (ir != JTAG_DPACC) {
1441 JTAG_IR(JTAG_DPACC);
1442 }
1443 request_value = DP_RDBUFF | DAP_TRANSFER_RnW;
1444 }
1445 retry = DAP_Data.transfer.retry_count;
1446 do {
1447 response_value = JTAG_Transfer(request_value, &data);
1448 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1449 if (response_value != DAP_TRANSFER_OK) {
1450 goto end;
1451 }
1452 // Store data
1453 *response++ = (uint8_t) data;
1454 *response++ = (uint8_t)(data >> 8);
1455 *response++ = (uint8_t)(data >> 16);
1456 *response++ = (uint8_t)(data >> 24);
1457 response_count++;
1458 }
1459 } else {
1460 // Write register block
1461 while (request_count--) {
1462 // Load data
1463 data = (uint32_t)(*(request+0) << 0) |
1464 (uint32_t)(*(request+1) << 8) |
1465 (uint32_t)(*(request+2) << 16) |
1466 (uint32_t)(*(request+3) << 24);
1467 request += 4;
1468 // Write DP/AP register
1469 retry = DAP_Data.transfer.retry_count;
1470 do {
1471 response_value = JTAG_Transfer(request_value, &data);
1472 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1473 if (response_value != DAP_TRANSFER_OK) {
1474 goto end;
1475 }
1476 response_count++;
1477 }
1478 // Check last write
1479 if (ir != JTAG_DPACC) {
1480 JTAG_IR(JTAG_DPACC);
1481 }
1482 retry = DAP_Data.transfer.retry_count;
1483 do {
1484 response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
1485 } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
1486 }
1487
1488end:
1489 *(response_head+0) = (uint8_t)(response_count >> 0);
1490 *(response_head+1) = (uint8_t)(response_count >> 8);
1491 *(response_head+2) = (uint8_t) response_value;
1492
1493 return ((uint32_t)(response - response_head));
1494}
1495#endif
1496
1497
1498// Process Transfer Block command and prepare response
1499// request: pointer to request data
1500// response: pointer to response data
1501// return: number of bytes in response (lower 16 bits)
1502// number of bytes in request (upper 16 bits)
1503static uint32_t DAP_TransferBlock(const uint8_t *request, uint8_t *response) {
1504 uint32_t num;
1505
1506 switch (DAP_Data.debug_port) {
1507#if (DAP_SWD != 0)
1508 case DAP_PORT_SWD:
1509 num = DAP_SWD_TransferBlock (request, response);
1510 break;
1511#endif
1512#if (DAP_JTAG != 0)
1513 case DAP_PORT_JTAG:
1514 num = DAP_JTAG_TransferBlock(request, response);
1515 break;
1516#endif
1517 default:
1518 *(response+0) = 0U; // Response count [7:0]
1519 *(response+1) = 0U; // Response count[15:8]
1520 *(response+2) = 0U; // Response value
1521 num = 3U;
1522 break;
1523 }
1524
1525 if ((*(request+3) & DAP_TRANSFER_RnW) != 0U) {
1526 // Read register block
1527 num |= 4U << 16;
1528 } else {
1529 // Write register block
1530 num |= (4U + (((uint32_t)(*(request+1)) | (uint32_t)(*(request+2) << 8)) * 4)) << 16;
1531 }
1532
1533 return (num);
1534}
1535
1536
1537// Process SWD Write ABORT command and prepare response
1538// request: pointer to request data
1539// response: pointer to response data
1540// return: number of bytes in response
1541#if (DAP_SWD != 0)
1542static uint32_t DAP_SWD_WriteAbort(const uint8_t *request, uint8_t *response) {
1543 uint32_t data;
1544
1545 // Load data (Ignore DAP index)
1546 data = (uint32_t)(*(request+1) << 0) |
1547 (uint32_t)(*(request+2) << 8) |
1548 (uint32_t)(*(request+3) << 16) |
1549 (uint32_t)(*(request+4) << 24);
1550
1551 // Write Abort register
1552 SWD_Transfer(DP_ABORT, &data);
1553
1554 *response = DAP_OK;
1555 return (1U);
1556}
1557#endif
1558
1559
1560// Process JTAG Write ABORT command and prepare response
1561// request: pointer to request data
1562// response: pointer to response data
1563// return: number of bytes in response
1564#if (DAP_JTAG != 0)
1565static uint32_t DAP_JTAG_WriteAbort(const uint8_t *request, uint8_t *response) {
1566 uint32_t data;
1567
1568 // Device index (JTAP TAP)
1569 DAP_Data.jtag_dev.index = *request;
1570 if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
1571 *response = DAP_ERROR;
1572 return (1U);
1573 }
1574
1575 // Select JTAG chain
1576 JTAG_IR(JTAG_ABORT);
1577
1578 // Load data
1579 data = (uint32_t)(*(request+1) << 0) |
1580 (uint32_t)(*(request+2) << 8) |
1581 (uint32_t)(*(request+3) << 16) |
1582 (uint32_t)(*(request+4) << 24);
1583
1584 // Write Abort register
1585 JTAG_WriteAbort(data);
1586
1587 *response = DAP_OK;
1588 return (1U);
1589}
1590#endif
1591
1592
1593// Process Write ABORT command and prepare response
1594// request: pointer to request data
1595// response: pointer to response data
1596// return: number of bytes in response (lower 16 bits)
1597// number of bytes in request (upper 16 bits)
1598static uint32_t DAP_WriteAbort(const uint8_t *request, uint8_t *response) {
1599 uint32_t num;
1600
1601 switch (DAP_Data.debug_port) {
1602#if (DAP_SWD != 0)
1603 case DAP_PORT_SWD:
1604 num = DAP_SWD_WriteAbort (request, response);
1605 break;
1606#endif
1607#if (DAP_JTAG != 0)
1608 case DAP_PORT_JTAG:
1609 num = DAP_JTAG_WriteAbort(request, response);
1610 break;
1611#endif
1612 default:
1613 *response = DAP_ERROR;
1614 num = 1U;
1615 break;
1616 }
1617 return ((5U << 16) | num);
1618}
1619
1620
1621// Process DAP Vendor command request and prepare response
1622// Default function (can be overridden)
1623// request: pointer to request data
1624// response: pointer to response data
1625// return: number of bytes in response (lower 16 bits)
1626// number of bytes in request (upper 16 bits)
1627__WEAK uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) {
1628 (void)request;
1629 *response = ID_DAP_Invalid;
1630 return ((1U << 16) | 1U);
1631}
1632
1633
1634// Process DAP command request and prepare response
1635// request: pointer to request data
1636// response: pointer to response data
1637// return: number of bytes in response (lower 16 bits)
1638// number of bytes in request (upper 16 bits)
1639uint32_t DAP_ProcessCommand(const uint8_t *request, uint8_t *response) {
1640 uint32_t num;
1641
1642 if ((*request >= ID_DAP_Vendor0) && (*request <= ID_DAP_Vendor31)) {
1643 return DAP_ProcessVendorCommand(request, response);
1644 }
1645
1646 *response++ = *request;
1647
1648 switch (*request++) {
1649 case ID_DAP_Info:
1650 num = DAP_Info(*request, response+1);
1651 *response = (uint8_t)num;
1652 return ((2U << 16) + 2U + num);
1653
1654 case ID_DAP_HostStatus:
1655 num = DAP_HostStatus(request, response);
1656 break;
1657
1658 case ID_DAP_Connect:
1659 num = DAP_Connect(request, response);
1660 break;
1661 case ID_DAP_Disconnect:
1662 num = DAP_Disconnect(response);
1663 break;
1664
1665 case ID_DAP_Delay:
1666 num = DAP_Delay(request, response);
1667 break;
1668
1669 case ID_DAP_ResetTarget:
1670 num = DAP_ResetTarget(response);
1671 break;
1672
1673 case ID_DAP_SWJ_Pins:
1674 num = DAP_SWJ_Pins(request, response);
1675 break;
1676 case ID_DAP_SWJ_Clock:
1677 num = DAP_SWJ_Clock(request, response);
1678 break;
1679 case ID_DAP_SWJ_Sequence:
1680 num = DAP_SWJ_Sequence(request, response);
1681 break;
1682
1683 case ID_DAP_SWD_Configure:
1684 num = DAP_SWD_Configure(request, response);
1685 break;
1686 case ID_DAP_SWD_Sequence:
1687 num = DAP_SWD_Sequence(request, response);
1688 break;
1689
1690 case ID_DAP_JTAG_Sequence:
1691 num = DAP_JTAG_Sequence(request, response);
1692 break;
1693 case ID_DAP_JTAG_Configure:
1694 num = DAP_JTAG_Configure(request, response);
1695 break;
1696 case ID_DAP_JTAG_IDCODE:
1697 num = DAP_JTAG_IDCode(request, response);
1698 break;
1699
1700 case ID_DAP_TransferConfigure:
1701 num = DAP_TransferConfigure(request, response);
1702 break;
1703 case ID_DAP_Transfer:
1704 num = DAP_Transfer(request, response);
1705 break;
1706 case ID_DAP_TransferBlock:
1707 num = DAP_TransferBlock(request, response);
1708 break;
1709
1710 case ID_DAP_WriteABORT:
1711 num = DAP_WriteAbort(request, response);
1712 break;
1713
1714#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
1715 case ID_DAP_SWO_Transport:
1716 num = SWO_Transport(request, response);
1717 break;
1718 case ID_DAP_SWO_Mode:
1719 num = SWO_Mode(request, response);
1720 break;
1721 case ID_DAP_SWO_Baudrate:
1722 num = SWO_Baudrate(request, response);
1723 break;
1724 case ID_DAP_SWO_Control:
1725 num = SWO_Control(request, response);
1726 break;
1727 case ID_DAP_SWO_Status:
1728 num = SWO_Status(response);
1729 break;
1730 case ID_DAP_SWO_ExtendedStatus:
1731 num = SWO_ExtendedStatus(request, response);
1732 break;
1733 case ID_DAP_SWO_Data:
1734 num = SWO_Data(request, response);
1735 break;
1736#endif
1737
1738#if (DAP_UART != 0)
1739 case ID_DAP_UART_Transport:
1740 num = UART_Transport(request, response);
1741 break;
1742 case ID_DAP_UART_Configure:
1743 num = UART_Configure(request, response);
1744 break;
1745 case ID_DAP_UART_Control:
1746 num = UART_Control(request, response);
1747 break;
1748 case ID_DAP_UART_Status:
1749 num = UART_Status(response);
1750 break;
1751 case ID_DAP_UART_Transfer:
1752 num = UART_Transfer(request, response);
1753 break;
1754#endif
1755
1756 default:
1757 *(response-1) = ID_DAP_Invalid;
1758 return ((1U << 16) | 1U);
1759 }
1760
1761 return ((1U << 16) + 1U + num);
1762}
1763
1764
1765// Execute DAP command (process request and prepare response)
1766// request: pointer to request data
1767// response: pointer to response data
1768// return: number of bytes in response (lower 16 bits)
1769// number of bytes in request (upper 16 bits)
1770uint32_t DAP_ExecuteCommand(const uint8_t *request, uint8_t *response) {
1771 uint32_t cnt, num, n;
1772
1773 if (*request == ID_DAP_ExecuteCommands) {
1774 *response++ = *request++;
1775 cnt = *request++;
1776 *response++ = (uint8_t)cnt;
1777 num = (2U << 16) | 2U;
1778 while (cnt--) {
1779 n = DAP_ProcessCommand(request, response);
1780 num += n;
1781 request += (uint16_t)(n >> 16);
1782 response += (uint16_t) n;
1783 }
1784 return (num);
1785 }
1786
1787 return DAP_ProcessCommand(request, response);
1788}
1789
1790
1791// Setup DAP
1792void DAP_Setup(void) {
1793
1794 // Default settings
1795 DAP_Data.debug_port = 0U;
1796 DAP_Data.transfer.idle_cycles = 0U;
1797 DAP_Data.transfer.retry_count = 100U;
1798 DAP_Data.transfer.match_retry = 0U;
1799 DAP_Data.transfer.match_mask = 0x00000000U;
1800#if (DAP_SWD != 0)
1801 DAP_Data.swd_conf.turnaround = 1U;
1802 DAP_Data.swd_conf.data_phase = 0U;
1803#endif
1804#if (DAP_JTAG != 0)
1805 DAP_Data.jtag_dev.count = 0U;
1806#endif
1807
1808 // Sets DAP_Data.fast_clock and DAP_Data.clock_delay.
1809 Set_Clock_Delay(DAP_DEFAULT_SWJ_CLOCK);
1810
1811 DAP_SETUP(); // Device specific setup
1812}
Note: See TracBrowser for help on using the repository browser.