1 /***************************************************************************
2 * Copyright (C) 2013 by mike brown *
3 * mike@theshedworks.org.uk *
5 * Copyright (C) 2013 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
22 ***************************************************************************/
28 #include <transport/transport.h>
30 #include <jtag/interface.h>
31 #include <jtag/commands.h>
36 #ifdef _DEBUG_JTAG_IO_
37 #define DEBUG_IO(expr...) LOG_DEBUG(expr)
39 #define DEBUG_IO(expr...) do {} while (0)
43 * See CMSIS-DAP documentation:
44 * Version 0.01 - Beta.
49 /* Known vid/pid pairs:
50 * VID 0xc251: Keil Software
51 * PID 0xf001: LPC-Link-II CMSIS_DAP
52 * PID 0xf002: OPEN-SDA CMSIS_DAP (Freedom Board)
53 * PID 0x2722: Keil ULINK2 CMSIS-DAP
55 * VID 0x0d28: mbed Software
56 * PID 0x0204: MBED CMSIS-DAP
60 /* vid = pid = 0 marks the end of the list */
61 static uint16_t cmsis_dap_vid
[MAX_USB_IDS
+ 1] = { 0 };
62 static uint16_t cmsis_dap_pid
[MAX_USB_IDS
+ 1] = { 0 };
64 #define PACKET_SIZE (64 + 1) /* 64 bytes plus report id */
65 #define USB_TIMEOUT 1000
67 /* CMSIS-DAP General Commands */
68 #define CMD_DAP_INFO 0x00
69 #define CMD_DAP_LED 0x01
70 #define CMD_DAP_CONNECT 0x02
71 #define CMD_DAP_DISCONNECT 0x03
72 #define CMD_DAP_WRITE_ABORT 0x08
73 #define CMD_DAP_DELAY 0x09
74 #define CMD_DAP_RESET_TARGET 0x0A
77 #define INFO_ID_VID 0x00 /* string */
78 #define INFO_ID_PID 0x02 /* string */
79 #define INFO_ID_SERNUM 0x03 /* string */
80 #define INFO_ID_FW_VER 0x04 /* string */
81 #define INFO_ID_TD_VEND 0x05 /* string */
82 #define INFO_ID_TD_NAME 0x06 /* string */
83 #define INFO_ID_CAPS 0xf0 /* byte */
84 #define INFO_ID_PKT_CNT 0xfe /* byte */
85 #define INFO_ID_PKT_SZ 0xff /* short */
87 #define INFO_CAPS_SWD 0x01
88 #define INFO_CAPS_JTAG 0x02
91 #define LED_ID_CONNECT 0x00
92 #define LED_ID_RUN 0x01
98 #define CONNECT_DEFAULT 0x00
99 #define CONNECT_SWD 0x01
100 #define CONNECT_JTAG 0x02
102 /* CMSIS-DAP Common SWD/JTAG Commands */
103 #define CMD_DAP_DELAY 0x09
104 #define CMD_DAP_SWJ_PINS 0x10
105 #define CMD_DAP_SWJ_CLOCK 0x11
106 #define CMD_DAP_SWJ_SEQ 0x12
118 /* CMSIS-DAP SWD Commands */
119 #define CMD_DAP_SWD_CONFIGURE 0x13
121 /* CMSIS-DAP JTAG Commands */
122 #define CMD_DAP_JTAG_SEQ 0x14
123 #define CMD_DAP_JTAG_CONFIGURE 0x15
124 #define CMD_DAP_JTAG_IDCODE 0x16
126 /* CMSIS-DAP Transfer Commands */
127 #define CMD_DAP_TFER_CONFIGURE 0x04
128 #define CMD_DAP_TFER 0x05
129 #define CMD_DAP_TFER_BLOCK 0x06
130 #define CMD_DAP_TFER_ABORT 0x07
132 /* DAP Status Code */
134 #define DAP_ERROR 0xFF
136 /* CMSIS-DAP Vendor Commands
139 static char *info_caps_str
[] = {
144 /* max clock speed (kHz) */
145 #define DAP_MAX_CLOCK 5000
148 hid_device
*dev_handle
;
149 uint16_t packet_size
;
150 uint16_t packet_count
;
151 uint8_t *packet_buffer
;
156 static struct cmsis_dap
*cmsis_dap_handle
;
158 static int cmsis_dap_usb_open(void)
160 hid_device
*dev
= NULL
;
162 struct hid_device_info
*devs
, *cur_dev
;
163 unsigned short target_vid
, target_pid
;
169 The CMSIS-DAP specification stipulates:
170 "The Product String must contain "CMSIS-DAP" somewhere in the string. This is used by the
171 debuggers to idenify a CMSIS-DAP compliant Debug Unit that is connected to a host computer."
173 devs
= hid_enumerate(0x0, 0x0);
175 while (NULL
!= cur_dev
) {
176 if ((0 == cmsis_dap_vid
[0]) && wcsstr(cur_dev
->product_string
, L
"CMSIS-DAP")) {
178 if the user hasn't specified VID:PID *and*
179 product string contains "CMSIS-DAP", pick it
184 otherwise, exhaustively compare against all VID:PID in list
186 for (i
= 0; cmsis_dap_vid
[i
] || cmsis_dap_pid
[i
]; i
++) {
187 if ((cmsis_dap_vid
[i
] == cur_dev
->vendor_id
) && (cmsis_dap_pid
[i
] == cur_dev
->product_id
))
192 cur_dev
= cur_dev
->next
;
195 if (NULL
!= cur_dev
) {
196 target_vid
= cur_dev
->vendor_id
;
197 target_pid
= cur_dev
->product_id
;
200 hid_free_enumeration(devs
);
202 if (hid_init() != 0) {
203 LOG_ERROR("unable to open HIDAPI");
207 dev
= hid_open(target_vid
, target_pid
, NULL
);
210 LOG_ERROR("unable to open CMSIS-DAP device");
214 struct cmsis_dap
*dap
= malloc(sizeof(struct cmsis_dap
));
216 LOG_ERROR("unable to allocate memory");
220 dap
->dev_handle
= dev
;
224 cmsis_dap_handle
= dap
;
226 /* allocate default packet buffer, may be changed later.
227 * currently with HIDAPI we have no way of getting the output report length
228 * without this info we cannot communicate with the adapter.
229 * For the moment we ahve to hard code the packet size */
231 int packet_size
= PACKET_SIZE
;
233 /* atmel cmsis-dap uses 512 byte reports */
234 if (target_vid
== 0x03eb && target_pid
== 0x2111)
235 packet_size
= 512 + 1;
237 cmsis_dap_handle
->packet_buffer
= malloc(packet_size
);
238 cmsis_dap_handle
->packet_size
= packet_size
;
240 if (cmsis_dap_handle
->packet_buffer
== NULL
) {
241 LOG_ERROR("unable to allocate memory");
248 static void cmsis_dap_usb_close(struct cmsis_dap
*dap
)
250 hid_close(dap
->dev_handle
);
253 if (cmsis_dap_handle
->packet_buffer
)
254 free(cmsis_dap_handle
->packet_buffer
);
256 if (cmsis_dap_handle
) {
257 free(cmsis_dap_handle
);
258 cmsis_dap_handle
= NULL
;
264 /* Send a message and receive the reply */
265 static int cmsis_dap_usb_xfer(struct cmsis_dap
*dap
, int txlen
)
267 /* Pad the rest of the TX buffer with 0's */
268 memset(dap
->packet_buffer
+ txlen
, 0, dap
->packet_size
- 1 - txlen
);
270 /* write data to device */
271 int retval
= hid_write(dap
->dev_handle
, dap
->packet_buffer
, dap
->packet_size
);
273 LOG_ERROR("error writing data: %ls", hid_error(dap
->dev_handle
));
278 retval
= hid_read_timeout(dap
->dev_handle
, dap
->packet_buffer
, dap
->packet_size
, USB_TIMEOUT
);
279 if (retval
== -1 || retval
== 0) {
280 LOG_DEBUG("error reading data: %ls", hid_error(dap
->dev_handle
));
287 static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins
, uint8_t mask
, uint32_t delay
, uint8_t *input
)
290 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
292 buffer
[0] = 0; /* report number */
293 buffer
[1] = CMD_DAP_SWJ_PINS
;
296 buffer
[4] = delay
& 0xff;
297 buffer
[5] = (delay
>> 8) & 0xff;
298 buffer
[6] = (delay
>> 16) & 0xff;
299 buffer
[7] = (delay
>> 24) & 0xff;
300 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 8);
302 if (retval
!= ERROR_OK
) {
303 LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_PINS failed.");
304 return ERROR_JTAG_DEVICE_ERROR
;
313 static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock
)
316 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
318 /* set clock in Hz */
320 buffer
[0] = 0; /* report number */
321 buffer
[1] = CMD_DAP_SWJ_CLOCK
;
322 buffer
[2] = swj_clock
& 0xff;
323 buffer
[3] = (swj_clock
>> 8) & 0xff;
324 buffer
[4] = (swj_clock
>> 16) & 0xff;
325 buffer
[5] = (swj_clock
>> 24) & 0xff;
326 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 6);
328 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
329 LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_CLOCK failed.");
330 return ERROR_JTAG_DEVICE_ERROR
;
336 static int cmsis_dap_cmd_DAP_Info(uint8_t info
, uint8_t **data
)
339 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
341 buffer
[0] = 0; /* report number */
342 buffer
[1] = CMD_DAP_INFO
;
344 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 3);
346 if (retval
!= ERROR_OK
) {
347 LOG_ERROR("CMSIS-DAP command CMD_INFO failed.");
348 return ERROR_JTAG_DEVICE_ERROR
;
351 *data
= &(buffer
[1]);
356 static int cmsis_dap_cmd_DAP_LED(uint8_t leds
)
359 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
361 buffer
[0] = 0; /* report number */
362 buffer
[1] = CMD_DAP_LED
;
365 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 4);
367 if (retval
!= ERROR_OK
|| buffer
[1] != 0x00) {
368 LOG_ERROR("CMSIS-DAP command CMD_LED failed.");
369 return ERROR_JTAG_DEVICE_ERROR
;
375 static int cmsis_dap_cmd_DAP_Connect(uint8_t mode
)
378 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
380 buffer
[0] = 0; /* report number */
381 buffer
[1] = CMD_DAP_CONNECT
;
383 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 3);
385 if (retval
!= ERROR_OK
) {
386 LOG_ERROR("CMSIS-DAP command CMD_CONNECT failed.");
387 return ERROR_JTAG_DEVICE_ERROR
;
390 if (buffer
[1] != mode
) {
391 LOG_ERROR("CMSIS-DAP failed to connect in mode (%d)", mode
);
392 return ERROR_JTAG_DEVICE_ERROR
;
398 static int cmsis_dap_cmd_DAP_Disconnect(void)
401 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
403 buffer
[0] = 0; /* report number */
404 buffer
[1] = CMD_DAP_DISCONNECT
;
405 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 2);
407 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
408 LOG_ERROR("CMSIS-DAP command CMD_DISCONNECT failed.");
409 return ERROR_JTAG_DEVICE_ERROR
;
415 static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle
, uint16_t delay
, uint16_t retry
)
418 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
420 buffer
[0] = 0; /* report number */
421 buffer
[1] = CMD_DAP_TFER_CONFIGURE
;
423 buffer
[3] = delay
& 0xff;
424 buffer
[4] = (delay
>> 8) & 0xff;
425 buffer
[5] = retry
& 0xff;
426 buffer
[6] = (retry
>> 8) & 0xff;
427 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 7);
429 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
430 LOG_ERROR("CMSIS-DAP command CMD_TFER_Configure failed.");
431 return ERROR_JTAG_DEVICE_ERROR
;
437 static int cmsis_dap_cmd_DAP_SWD_Configure(uint8_t cfg
)
440 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
442 buffer
[0] = 0; /* report number */
443 buffer
[1] = CMD_DAP_SWD_CONFIGURE
;
445 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 3);
447 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
448 LOG_ERROR("CMSIS-DAP command CMD_SWD_Configure failed.");
449 return ERROR_JTAG_DEVICE_ERROR
;
456 static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us
)
459 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
461 buffer
[0] = 0; /* report number */
462 buffer
[1] = CMD_DAP_DELAY
;
463 buffer
[2] = delay_us
& 0xff;
464 buffer
[3] = (delay_us
>> 8) & 0xff;
465 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 4);
467 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
468 LOG_ERROR("CMSIS-DAP command CMD_Delay failed.");
469 return ERROR_JTAG_DEVICE_ERROR
;
476 static int cmsis_dap_swd_read_reg(uint8_t cmd
, uint32_t *value
)
478 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
482 DEBUG_IO("CMSIS-DAP: Read Reg 0x%02" PRIx8
, cmd
);
484 buffer
[0] = 0; /* report number */
485 buffer
[1] = CMD_DAP_TFER
;
489 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 5);
491 /* TODO - need better response checking */
492 if (retval
!= ERROR_OK
|| buffer
[1] != 0x01) {
493 LOG_ERROR("CMSIS-DAP: Read Error (0x%02" PRIx8
")", buffer
[2]);
497 val
= le_to_h_u32(&buffer
[3]);
498 DEBUG_IO("0x%08" PRIx32
, val
);
506 static int cmsis_dap_swd_write_reg(uint8_t cmd
, uint32_t value
)
508 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
510 DEBUG_IO("CMSIS-DAP: Write Reg 0x%02" PRIx8
" 0x%08" PRIx32
, cmd
, value
);
512 buffer
[0] = 0; /* report number */
513 buffer
[1] = CMD_DAP_TFER
;
517 buffer
[5] = (value
) & 0xff;
518 buffer
[6] = (value
>> 8) & 0xff;
519 buffer
[7] = (value
>> 16) & 0xff;
520 buffer
[8] = (value
>> 24) & 0xff;
521 int retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 9);
523 if (buffer
[1] != 0x01) {
524 LOG_ERROR("CMSIS-DAP: Write Error (0x%02" PRIx8
")", buffer
[2]);
531 static int cmsis_dap_swd_read_block(uint8_t cmd
, uint32_t blocksize
, uint8_t *dest_buf
)
535 int retval
= ERROR_OK
;
538 DEBUG_IO("CMSIS-DAP: Read Block 0x%02" PRIx8
" %" PRIu32
, cmd
, blocksize
);
542 buffer
= cmsis_dap_handle
->packet_buffer
;
547 buffer
[0] = 0; /* report number */
548 buffer
[1] = CMD_DAP_TFER_BLOCK
;
553 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 6);
555 read_count
= le_to_h_u16(&buffer
[1]);
556 if (read_count
!= tfer_sz
) {
557 LOG_ERROR("CMSIS-DAP: Block Read Error (0x%02" PRIx8
")", buffer
[3]);
562 memcpy(dest_buf
, &buffer
[4], read_count
);
564 dest_buf
+= read_count
;
565 blocksize
-= tfer_sz
;
571 static int cmsis_dap_get_version_info(void)
575 /* INFO_ID_FW_VER - string */
576 int retval
= cmsis_dap_cmd_DAP_Info(INFO_ID_FW_VER
, &data
);
577 if (retval
!= ERROR_OK
)
580 if (data
[0]) /* strlen */
581 LOG_INFO("CMSIS-DAP: FW Version = %s", &data
[1]);
586 static int cmsis_dap_get_caps_info(void)
590 /* INFO_ID_CAPS - byte */
591 int retval
= cmsis_dap_cmd_DAP_Info(INFO_ID_CAPS
, &data
);
592 if (retval
!= ERROR_OK
)
596 uint8_t caps
= data
[1];
598 cmsis_dap_handle
->caps
= caps
;
600 if (caps
& INFO_CAPS_SWD
)
601 LOG_INFO("CMSIS-DAP: %s", info_caps_str
[0]);
602 if (caps
& INFO_CAPS_JTAG
)
603 LOG_INFO("CMSIS-DAP: %s", info_caps_str
[1]);
609 static int cmsis_dap_get_status(void)
613 int retval
= cmsis_dap_cmd_DAP_SWJ_Pins(0, 0, 0, &d
);
615 if (retval
== ERROR_OK
) {
616 LOG_INFO("SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d",
617 (d
& (0x01 << 0)) ? 1 : 0, /* Bit 0: SWCLK/TCK */
618 (d
& (0x01 << 1)) ? 1 : 0, /* Bit 1: SWDIO/TMS */
619 (d
& (0x01 << 2)) ? 1 : 0, /* Bit 2: TDI */
620 (d
& (0x01 << 3)) ? 1 : 0, /* Bit 3: TDO */
621 (d
& (0x01 << 5)) ? 1 : 0, /* Bit 5: nTRST */
622 (d
& (0x01 << 7)) ? 1 : 0); /* Bit 7: nRESET */
628 static int cmsis_dap_reset_link(void)
630 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
632 LOG_DEBUG("CMSIS-DAP: cmsis_dap_reset_link");
633 LOG_INFO("DAP_SWJ Sequence (reset: 50+ '1' followed by 0)");
635 /* reset line with SWDIO high for >50 cycles */
636 buffer
[0] = 0; /* report number */
637 buffer
[1] = CMD_DAP_SWJ_SEQ
;
646 int retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 10);
648 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
)
651 /* 16bit JTAG-SWD sequence */
652 buffer
[0] = 0; /* report number */
653 buffer
[1] = CMD_DAP_SWJ_SEQ
;
657 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 5);
659 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
)
662 /* another reset just incase */
663 buffer
[0] = 0; /* report number */
664 buffer
[1] = CMD_DAP_SWJ_SEQ
;
673 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 10);
675 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
)
678 /* 16 cycle idle period */
679 buffer
[0] = 0; /* report number */
680 buffer
[1] = CMD_DAP_SWJ_SEQ
;
684 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 5);
686 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
)
689 DEBUG_IO("DAP Read IDCODE");
691 /* read the id code is always the next sequence */
692 buffer
[0] = 0; /* report number */
693 buffer
[1] = CMD_DAP_TFER
;
697 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 5);
699 if (retval
!= ERROR_OK
)
702 if (buffer
[1] == 0) {
703 LOG_DEBUG("Result 0x%02" PRIx8
" 0x%02" PRIx8
, buffer
[1], buffer
[2]);
705 LOG_DEBUG("DAP Reset Target");
706 buffer
[0] = 0; /* report number */
707 buffer
[1] = CMD_DAP_RESET_TARGET
;
708 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 2);
709 LOG_DEBUG("Result 0x%02" PRIx8
" 0x%02" PRIx8
, buffer
[1], buffer
[2]);
711 LOG_DEBUG("DAP Write Abort");
712 buffer
[0] = 0; /* report number */
713 buffer
[1] = CMD_DAP_WRITE_ABORT
;
715 buffer
[3] = 0x1e/*0x1f*/;
719 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 7);
720 LOG_DEBUG("Result 0x%02" PRIx8
, buffer
[1]);
722 return 0x80 + buffer
[1];
725 LOG_DEBUG("DAP Write Abort");
726 buffer
[0] = 0; /* report number */
727 buffer
[1] = CMD_DAP_WRITE_ABORT
;
733 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 7);
734 LOG_DEBUG("Result 0x%02" PRIx8
, buffer
[1]);
739 static int cmsis_dap_init(void)
744 if (cmsis_dap_handle
== NULL
) {
747 retval
= cmsis_dap_usb_open();
748 if (retval
!= ERROR_OK
)
751 retval
= cmsis_dap_get_caps_info();
752 if (retval
!= ERROR_OK
)
755 /* Connect in JTAG mode */
756 if (!(cmsis_dap_handle
->caps
& INFO_CAPS_JTAG
)) {
757 LOG_ERROR("CMSIS-DAP: JTAG not supported");
758 return ERROR_JTAG_DEVICE_ERROR
;
761 retval
= cmsis_dap_cmd_DAP_Connect(CONNECT_JTAG
);
762 if (retval
!= ERROR_OK
)
765 LOG_INFO("CMSIS-DAP: Interface Initialised (JTAG)");
768 retval
= cmsis_dap_get_version_info();
769 if (retval
!= ERROR_OK
)
772 /* INFO_ID_PKT_SZ - short */
773 retval
= cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_SZ
, &data
);
774 if (retval
!= ERROR_OK
)
777 if (data
[0] == 2) { /* short */
778 uint16_t pkt_sz
= data
[1] + (data
[2] << 8);
780 if (cmsis_dap_handle
->packet_size
!= pkt_sz
+ 1) {
781 /* reallocate buffer */
782 cmsis_dap_handle
->packet_size
= pkt_sz
+ 1;
783 cmsis_dap_handle
->packet_buffer
= realloc(cmsis_dap_handle
->packet_buffer
,
784 cmsis_dap_handle
->packet_size
);
785 if (cmsis_dap_handle
->packet_buffer
== NULL
) {
786 LOG_ERROR("unable to reallocate memory");
791 LOG_DEBUG("CMSIS-DAP: Packet Size = %" PRId16
, pkt_sz
);
794 /* INFO_ID_PKT_CNT - byte */
795 retval
= cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_CNT
, &data
);
796 if (retval
!= ERROR_OK
)
799 if (data
[0] == 1) { /* byte */
800 uint16_t pkt_cnt
= data
[1];
801 cmsis_dap_handle
->packet_count
= pkt_cnt
;
802 LOG_DEBUG("CMSIS-DAP: Packet Count = %" PRId16
, pkt_cnt
);
805 retval
= cmsis_dap_get_status();
806 if (retval
!= ERROR_OK
)
809 /* Now try to connect to the target
810 * TODO: This is all SWD only @ present */
811 retval
= cmsis_dap_cmd_DAP_SWJ_Clock(100); /* 100kHz */
812 if (retval
!= ERROR_OK
)
815 retval
= cmsis_dap_cmd_DAP_TFER_Configure(0, 64, 0);
816 if (retval
!= ERROR_OK
)
818 retval
= cmsis_dap_cmd_DAP_SWD_Configure(0x00);
819 if (retval
!= ERROR_OK
)
822 retval
= cmsis_dap_cmd_DAP_LED(0x03); /* Both LEDs on */
823 if (retval
!= ERROR_OK
)
826 /* support connecting with srst asserted */
827 enum reset_types jtag_reset_config
= jtag_get_reset_config();
829 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
830 if (jtag_reset_config
& RESET_SRST_NO_GATING
) {
831 retval
= cmsis_dap_cmd_DAP_SWJ_Pins(0, (1 << 7), 0, NULL
);
832 if (retval
!= ERROR_OK
)
834 LOG_INFO("Connecting under reset");
838 retval
= cmsis_dap_reset_link();
839 if (retval
!= ERROR_OK
)
842 cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */
844 LOG_INFO("CMSIS-DAP: Interface ready");
849 static int cmsis_dap_swd_init(uint8_t trn
)
853 DEBUG_IO("CMSIS-DAP: cmsis_dap_swd_init");
855 if (cmsis_dap_handle
== NULL
) {
858 retval
= cmsis_dap_usb_open();
859 if (retval
!= ERROR_OK
)
862 retval
= cmsis_dap_get_caps_info();
863 if (retval
!= ERROR_OK
)
867 if (!(cmsis_dap_handle
->caps
& INFO_CAPS_SWD
)) {
868 LOG_ERROR("CMSIS-DAP: SWD not supported");
869 return ERROR_JTAG_DEVICE_ERROR
;
872 retval
= cmsis_dap_cmd_DAP_Connect(CONNECT_SWD
);
873 if (retval
!= ERROR_OK
)
876 /* Add more setup here.??... */
878 LOG_INFO("CMSIS-DAP: Interface Initialised (SWD)");
882 static int cmsis_dap_quit(void)
884 cmsis_dap_cmd_DAP_Disconnect();
885 cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */
887 cmsis_dap_usb_close(cmsis_dap_handle
);
892 static void cmsis_dap_execute_reset(struct jtag_command
*cmd
)
894 int retval
= cmsis_dap_cmd_DAP_SWJ_Pins(cmd
->cmd
.reset
->srst
? 0 : (1 << 7), \
896 if (retval
!= ERROR_OK
)
897 LOG_ERROR("CMSIS-DAP: Interface reset failed");
900 static void cmsis_dap_execute_sleep(struct jtag_command
*cmd
)
903 int retval
= cmsis_dap_cmd_DAP_Delay(cmd
->cmd
.sleep
->us
);
904 if (retval
!= ERROR_OK
)
906 jtag_sleep(cmd
->cmd
.sleep
->us
);
909 static void cmsis_dap_execute_command(struct jtag_command
*cmd
)
913 cmsis_dap_execute_reset(cmd
);
916 cmsis_dap_execute_sleep(cmd
);
919 LOG_ERROR("BUG: unknown JTAG command type encountered");
924 static int cmsis_dap_execute_queue(void)
926 struct jtag_command
*cmd
= jtag_command_queue
;
928 while (cmd
!= NULL
) {
929 cmsis_dap_execute_command(cmd
);
936 static int cmsis_dap_speed(int speed
)
938 if (speed
> DAP_MAX_CLOCK
) {
939 LOG_INFO("reduce speed request: %dkHz to %dkHz maximum", speed
, DAP_MAX_CLOCK
);
940 speed
= DAP_MAX_CLOCK
;
944 LOG_INFO("RTCK not supported");
945 return ERROR_JTAG_NOT_IMPLEMENTED
;
948 return cmsis_dap_cmd_DAP_SWJ_Clock(speed
);
951 static int cmsis_dap_speed_div(int speed
, int *khz
)
957 static int cmsis_dap_khz(int khz
, int *jtag_speed
)
963 COMMAND_HANDLER(cmsis_dap_handle_info_command
)
965 if (cmsis_dap_get_version_info() == ERROR_OK
)
966 cmsis_dap_get_status();
971 COMMAND_HANDLER(cmsis_dap_handle_vid_pid_command
)
973 if (CMD_ARGC
> MAX_USB_IDS
* 2) {
974 LOG_WARNING("ignoring extra IDs in cmsis_dap_vid_pid "
975 "(maximum is %d pairs)", MAX_USB_IDS
);
976 CMD_ARGC
= MAX_USB_IDS
* 2;
978 if (CMD_ARGC
< 2 || (CMD_ARGC
& 1)) {
979 LOG_WARNING("incomplete cmsis_dap_vid_pid configuration directive");
981 return ERROR_COMMAND_SYNTAX_ERROR
;
982 /* remove the incomplete trailing id */
987 for (i
= 0; i
< CMD_ARGC
; i
+= 2) {
988 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[i
], cmsis_dap_vid
[i
>> 1]);
989 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[i
+ 1], cmsis_dap_pid
[i
>> 1]);
993 * Explicitly terminate, in case there are multiples instances of
996 cmsis_dap_vid
[i
>> 1] = cmsis_dap_pid
[i
>> 1] = 0;
1001 static const struct command_registration cmsis_dap_subcommand_handlers
[] = {
1004 .handler
= &cmsis_dap_handle_info_command
,
1005 .mode
= COMMAND_EXEC
,
1007 .help
= "show cmsis-dap info",
1009 COMMAND_REGISTRATION_DONE
1012 COMMAND_HANDLER(cmsis_dap_reset_command
)
1014 LOG_DEBUG("cmsis_dap_reset_command");
1018 COMMAND_HANDLER(cmsis_dap_jtag_command
)
1020 LOG_DEBUG("cmsis_dap_jtag_command");
1024 static const struct command_registration cmsis_dap_jtag_subcommand_handlers
[] = {
1027 .mode
= COMMAND_ANY
,
1028 .handler
= cmsis_dap_jtag_command
,
1033 .mode
= COMMAND_ANY
,
1034 .handler
= cmsis_dap_jtag_command
,
1038 .name
= "arp_init-reset",
1039 .mode
= COMMAND_ANY
,
1040 .handler
= cmsis_dap_reset_command
,
1044 .name
= "tapisenabled",
1045 .mode
= COMMAND_EXEC
,
1046 .jim_handler
= jim_jtag_tap_enabler
,
1049 .name
= "tapenable",
1050 .mode
= COMMAND_EXEC
,
1051 .jim_handler
= jim_jtag_tap_enabler
,
1054 .name
= "tapdisable",
1055 .mode
= COMMAND_EXEC
,
1056 .handler
= cmsis_dap_jtag_command
,
1060 .name
= "configure",
1061 .mode
= COMMAND_EXEC
,
1062 .handler
= cmsis_dap_jtag_command
,
1067 .mode
= COMMAND_EXEC
,
1068 .jim_handler
= jim_jtag_configure
,
1072 .mode
= COMMAND_ANY
,
1073 .handler
= cmsis_dap_jtag_command
,
1076 COMMAND_REGISTRATION_DONE
1079 static const struct command_registration cmsis_dap_command_handlers
[] = {
1081 .name
= "cmsis-dap",
1082 .mode
= COMMAND_ANY
,
1083 .help
= "perform CMSIS-DAP management",
1085 .chain
= cmsis_dap_subcommand_handlers
,
1088 .name
= "cmsis_dap_vid_pid",
1089 .handler
= &cmsis_dap_handle_vid_pid_command
,
1090 .mode
= COMMAND_CONFIG
,
1091 .help
= "the vendor ID and product ID of the CMSIS-DAP device",
1092 .usage
= "(vid pid)* ",
1095 /* this is currently a nasty hack so we get
1096 * reset working with non jtag interfaces */
1098 .mode
= COMMAND_ANY
,
1100 .chain
= cmsis_dap_jtag_subcommand_handlers
,
1102 COMMAND_REGISTRATION_DONE
1105 static const struct swd_driver cmsis_dap_swd_driver
= {
1106 .init
= cmsis_dap_swd_init
,
1107 .read_reg
= cmsis_dap_swd_read_reg
,
1108 .write_reg
= cmsis_dap_swd_write_reg
,
1109 .read_block
= cmsis_dap_swd_read_block
1112 const char *cmsis_dap_transport
[] = {"cmsis-dap", NULL
};
1114 struct jtag_interface cmsis_dap_interface
= {
1115 .name
= "cmsis-dap",
1116 .commands
= cmsis_dap_command_handlers
,
1117 .swd
= &cmsis_dap_swd_driver
,
1118 .transports
= cmsis_dap_transport
,
1120 .execute_queue
= cmsis_dap_execute_queue
,
1121 .speed
= cmsis_dap_speed
,
1122 .speed_div
= cmsis_dap_speed_div
,
1123 .khz
= cmsis_dap_khz
,
1124 .init
= cmsis_dap_init
,
1125 .quit
= cmsis_dap_quit
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)