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]) && (NULL
!= cur_dev
->product_string
)
177 && wcsstr(cur_dev
->product_string
, L
"CMSIS-DAP")) {
179 if the user hasn't specified VID:PID *and*
180 product string contains "CMSIS-DAP", pick it
185 otherwise, exhaustively compare against all VID:PID in list
187 for (i
= 0; cmsis_dap_vid
[i
] || cmsis_dap_pid
[i
]; i
++) {
188 if ((cmsis_dap_vid
[i
] == cur_dev
->vendor_id
) && (cmsis_dap_pid
[i
] == cur_dev
->product_id
))
193 cur_dev
= cur_dev
->next
;
196 if (NULL
!= cur_dev
) {
197 target_vid
= cur_dev
->vendor_id
;
198 target_pid
= cur_dev
->product_id
;
201 hid_free_enumeration(devs
);
203 if (hid_init() != 0) {
204 LOG_ERROR("unable to open HIDAPI");
208 dev
= hid_open(target_vid
, target_pid
, NULL
);
211 LOG_ERROR("unable to open CMSIS-DAP device");
215 struct cmsis_dap
*dap
= malloc(sizeof(struct cmsis_dap
));
217 LOG_ERROR("unable to allocate memory");
221 dap
->dev_handle
= dev
;
225 cmsis_dap_handle
= dap
;
227 /* allocate default packet buffer, may be changed later.
228 * currently with HIDAPI we have no way of getting the output report length
229 * without this info we cannot communicate with the adapter.
230 * For the moment we ahve to hard code the packet size */
232 int packet_size
= PACKET_SIZE
;
234 /* atmel cmsis-dap uses 512 byte reports */
235 if (target_vid
== 0x03eb && target_pid
== 0x2111)
236 packet_size
= 512 + 1;
238 cmsis_dap_handle
->packet_buffer
= malloc(packet_size
);
239 cmsis_dap_handle
->packet_size
= packet_size
;
241 if (cmsis_dap_handle
->packet_buffer
== NULL
) {
242 LOG_ERROR("unable to allocate memory");
249 static void cmsis_dap_usb_close(struct cmsis_dap
*dap
)
251 hid_close(dap
->dev_handle
);
254 if (cmsis_dap_handle
->packet_buffer
)
255 free(cmsis_dap_handle
->packet_buffer
);
257 if (cmsis_dap_handle
) {
258 free(cmsis_dap_handle
);
259 cmsis_dap_handle
= NULL
;
265 /* Send a message and receive the reply */
266 static int cmsis_dap_usb_xfer(struct cmsis_dap
*dap
, int txlen
)
268 /* Pad the rest of the TX buffer with 0's */
269 memset(dap
->packet_buffer
+ txlen
, 0, dap
->packet_size
- 1 - txlen
);
271 /* write data to device */
272 int retval
= hid_write(dap
->dev_handle
, dap
->packet_buffer
, dap
->packet_size
);
274 LOG_ERROR("error writing data: %ls", hid_error(dap
->dev_handle
));
279 retval
= hid_read_timeout(dap
->dev_handle
, dap
->packet_buffer
, dap
->packet_size
, USB_TIMEOUT
);
280 if (retval
== -1 || retval
== 0) {
281 LOG_DEBUG("error reading data: %ls", hid_error(dap
->dev_handle
));
288 static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins
, uint8_t mask
, uint32_t delay
, uint8_t *input
)
291 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
293 buffer
[0] = 0; /* report number */
294 buffer
[1] = CMD_DAP_SWJ_PINS
;
297 buffer
[4] = delay
& 0xff;
298 buffer
[5] = (delay
>> 8) & 0xff;
299 buffer
[6] = (delay
>> 16) & 0xff;
300 buffer
[7] = (delay
>> 24) & 0xff;
301 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 8);
303 if (retval
!= ERROR_OK
) {
304 LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_PINS failed.");
305 return ERROR_JTAG_DEVICE_ERROR
;
314 static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock
)
317 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
319 /* set clock in Hz */
321 buffer
[0] = 0; /* report number */
322 buffer
[1] = CMD_DAP_SWJ_CLOCK
;
323 buffer
[2] = swj_clock
& 0xff;
324 buffer
[3] = (swj_clock
>> 8) & 0xff;
325 buffer
[4] = (swj_clock
>> 16) & 0xff;
326 buffer
[5] = (swj_clock
>> 24) & 0xff;
327 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 6);
329 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
330 LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_CLOCK failed.");
331 return ERROR_JTAG_DEVICE_ERROR
;
337 static int cmsis_dap_cmd_DAP_Info(uint8_t info
, uint8_t **data
)
340 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
342 buffer
[0] = 0; /* report number */
343 buffer
[1] = CMD_DAP_INFO
;
345 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 3);
347 if (retval
!= ERROR_OK
) {
348 LOG_ERROR("CMSIS-DAP command CMD_INFO failed.");
349 return ERROR_JTAG_DEVICE_ERROR
;
352 *data
= &(buffer
[1]);
357 static int cmsis_dap_cmd_DAP_LED(uint8_t leds
)
360 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
362 buffer
[0] = 0; /* report number */
363 buffer
[1] = CMD_DAP_LED
;
366 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 4);
368 if (retval
!= ERROR_OK
|| buffer
[1] != 0x00) {
369 LOG_ERROR("CMSIS-DAP command CMD_LED failed.");
370 return ERROR_JTAG_DEVICE_ERROR
;
376 static int cmsis_dap_cmd_DAP_Connect(uint8_t mode
)
379 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
381 buffer
[0] = 0; /* report number */
382 buffer
[1] = CMD_DAP_CONNECT
;
384 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 3);
386 if (retval
!= ERROR_OK
) {
387 LOG_ERROR("CMSIS-DAP command CMD_CONNECT failed.");
388 return ERROR_JTAG_DEVICE_ERROR
;
391 if (buffer
[1] != mode
) {
392 LOG_ERROR("CMSIS-DAP failed to connect in mode (%d)", mode
);
393 return ERROR_JTAG_DEVICE_ERROR
;
399 static int cmsis_dap_cmd_DAP_Disconnect(void)
402 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
404 buffer
[0] = 0; /* report number */
405 buffer
[1] = CMD_DAP_DISCONNECT
;
406 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 2);
408 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
409 LOG_ERROR("CMSIS-DAP command CMD_DISCONNECT failed.");
410 return ERROR_JTAG_DEVICE_ERROR
;
416 static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle
, uint16_t delay
, uint16_t retry
)
419 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
421 buffer
[0] = 0; /* report number */
422 buffer
[1] = CMD_DAP_TFER_CONFIGURE
;
424 buffer
[3] = delay
& 0xff;
425 buffer
[4] = (delay
>> 8) & 0xff;
426 buffer
[5] = retry
& 0xff;
427 buffer
[6] = (retry
>> 8) & 0xff;
428 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 7);
430 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
431 LOG_ERROR("CMSIS-DAP command CMD_TFER_Configure failed.");
432 return ERROR_JTAG_DEVICE_ERROR
;
438 static int cmsis_dap_cmd_DAP_SWD_Configure(uint8_t cfg
)
441 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
443 buffer
[0] = 0; /* report number */
444 buffer
[1] = CMD_DAP_SWD_CONFIGURE
;
446 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 3);
448 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
449 LOG_ERROR("CMSIS-DAP command CMD_SWD_Configure failed.");
450 return ERROR_JTAG_DEVICE_ERROR
;
457 static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us
)
460 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
462 buffer
[0] = 0; /* report number */
463 buffer
[1] = CMD_DAP_DELAY
;
464 buffer
[2] = delay_us
& 0xff;
465 buffer
[3] = (delay_us
>> 8) & 0xff;
466 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 4);
468 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
) {
469 LOG_ERROR("CMSIS-DAP command CMD_Delay failed.");
470 return ERROR_JTAG_DEVICE_ERROR
;
477 static int cmsis_dap_swd_read_reg(uint8_t cmd
, uint32_t *value
)
479 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
483 DEBUG_IO("CMSIS-DAP: Read Reg 0x%02" PRIx8
, cmd
);
485 buffer
[0] = 0; /* report number */
486 buffer
[1] = CMD_DAP_TFER
;
490 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 5);
492 /* TODO - need better response checking */
493 if (retval
!= ERROR_OK
|| buffer
[1] != 0x01) {
494 LOG_ERROR("CMSIS-DAP: Read Error (0x%02" PRIx8
")", buffer
[2]);
498 val
= le_to_h_u32(&buffer
[3]);
499 DEBUG_IO("0x%08" PRIx32
, val
);
507 static int cmsis_dap_swd_write_reg(uint8_t cmd
, uint32_t value
)
509 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
511 DEBUG_IO("CMSIS-DAP: Write Reg 0x%02" PRIx8
" 0x%08" PRIx32
, cmd
, value
);
513 buffer
[0] = 0; /* report number */
514 buffer
[1] = CMD_DAP_TFER
;
518 buffer
[5] = (value
) & 0xff;
519 buffer
[6] = (value
>> 8) & 0xff;
520 buffer
[7] = (value
>> 16) & 0xff;
521 buffer
[8] = (value
>> 24) & 0xff;
522 int retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 9);
524 if (buffer
[1] != 0x01) {
525 LOG_ERROR("CMSIS-DAP: Write Error (0x%02" PRIx8
")", buffer
[2]);
532 static int cmsis_dap_swd_read_block(uint8_t cmd
, uint32_t blocksize
, uint8_t *dest_buf
)
536 int retval
= ERROR_OK
;
539 DEBUG_IO("CMSIS-DAP: Read Block 0x%02" PRIx8
" %" PRIu32
, cmd
, blocksize
);
543 buffer
= cmsis_dap_handle
->packet_buffer
;
548 buffer
[0] = 0; /* report number */
549 buffer
[1] = CMD_DAP_TFER_BLOCK
;
554 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 6);
556 read_count
= le_to_h_u16(&buffer
[1]);
557 if (read_count
!= tfer_sz
) {
558 LOG_ERROR("CMSIS-DAP: Block Read Error (0x%02" PRIx8
")", buffer
[3]);
563 memcpy(dest_buf
, &buffer
[4], read_count
);
565 dest_buf
+= read_count
;
566 blocksize
-= tfer_sz
;
572 static int cmsis_dap_get_version_info(void)
576 /* INFO_ID_FW_VER - string */
577 int retval
= cmsis_dap_cmd_DAP_Info(INFO_ID_FW_VER
, &data
);
578 if (retval
!= ERROR_OK
)
581 if (data
[0]) /* strlen */
582 LOG_INFO("CMSIS-DAP: FW Version = %s", &data
[1]);
587 static int cmsis_dap_get_caps_info(void)
591 /* INFO_ID_CAPS - byte */
592 int retval
= cmsis_dap_cmd_DAP_Info(INFO_ID_CAPS
, &data
);
593 if (retval
!= ERROR_OK
)
597 uint8_t caps
= data
[1];
599 cmsis_dap_handle
->caps
= caps
;
601 if (caps
& INFO_CAPS_SWD
)
602 LOG_INFO("CMSIS-DAP: %s", info_caps_str
[0]);
603 if (caps
& INFO_CAPS_JTAG
)
604 LOG_INFO("CMSIS-DAP: %s", info_caps_str
[1]);
610 static int cmsis_dap_get_status(void)
614 int retval
= cmsis_dap_cmd_DAP_SWJ_Pins(0, 0, 0, &d
);
616 if (retval
== ERROR_OK
) {
617 LOG_INFO("SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d",
618 (d
& (0x01 << 0)) ? 1 : 0, /* Bit 0: SWCLK/TCK */
619 (d
& (0x01 << 1)) ? 1 : 0, /* Bit 1: SWDIO/TMS */
620 (d
& (0x01 << 2)) ? 1 : 0, /* Bit 2: TDI */
621 (d
& (0x01 << 3)) ? 1 : 0, /* Bit 3: TDO */
622 (d
& (0x01 << 5)) ? 1 : 0, /* Bit 5: nTRST */
623 (d
& (0x01 << 7)) ? 1 : 0); /* Bit 7: nRESET */
629 static int cmsis_dap_reset_link(void)
631 uint8_t *buffer
= cmsis_dap_handle
->packet_buffer
;
633 LOG_DEBUG("CMSIS-DAP: cmsis_dap_reset_link");
634 LOG_INFO("DAP_SWJ Sequence (reset: 50+ '1' followed by 0)");
636 /* reset line with SWDIO high for >50 cycles */
637 buffer
[0] = 0; /* report number */
638 buffer
[1] = CMD_DAP_SWJ_SEQ
;
647 int retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 10);
649 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
)
652 /* 16bit JTAG-SWD sequence */
653 buffer
[0] = 0; /* report number */
654 buffer
[1] = CMD_DAP_SWJ_SEQ
;
658 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 5);
660 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
)
663 /* another reset just incase */
664 buffer
[0] = 0; /* report number */
665 buffer
[1] = CMD_DAP_SWJ_SEQ
;
674 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 10);
676 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
)
679 /* 16 cycle idle period */
680 buffer
[0] = 0; /* report number */
681 buffer
[1] = CMD_DAP_SWJ_SEQ
;
685 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 5);
687 if (retval
!= ERROR_OK
|| buffer
[1] != DAP_OK
)
690 DEBUG_IO("DAP Read IDCODE");
692 /* read the id code is always the next sequence */
693 buffer
[0] = 0; /* report number */
694 buffer
[1] = CMD_DAP_TFER
;
698 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 5);
700 if (retval
!= ERROR_OK
)
703 if (buffer
[1] == 0) {
704 LOG_DEBUG("Result 0x%02" PRIx8
" 0x%02" PRIx8
, buffer
[1], buffer
[2]);
706 LOG_DEBUG("DAP Reset Target");
707 buffer
[0] = 0; /* report number */
708 buffer
[1] = CMD_DAP_RESET_TARGET
;
709 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 2);
710 LOG_DEBUG("Result 0x%02" PRIx8
" 0x%02" PRIx8
, buffer
[1], buffer
[2]);
712 LOG_DEBUG("DAP Write Abort");
713 buffer
[0] = 0; /* report number */
714 buffer
[1] = CMD_DAP_WRITE_ABORT
;
716 buffer
[3] = 0x1e/*0x1f*/;
720 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 7);
721 LOG_DEBUG("Result 0x%02" PRIx8
, buffer
[1]);
723 return 0x80 + buffer
[1];
726 LOG_DEBUG("DAP Write Abort");
727 buffer
[0] = 0; /* report number */
728 buffer
[1] = CMD_DAP_WRITE_ABORT
;
734 retval
= cmsis_dap_usb_xfer(cmsis_dap_handle
, 7);
735 LOG_DEBUG("Result 0x%02" PRIx8
, buffer
[1]);
740 static int cmsis_dap_init(void)
745 if (cmsis_dap_handle
== NULL
) {
748 retval
= cmsis_dap_usb_open();
749 if (retval
!= ERROR_OK
)
752 retval
= cmsis_dap_get_caps_info();
753 if (retval
!= ERROR_OK
)
756 /* Connect in JTAG mode */
757 if (!(cmsis_dap_handle
->caps
& INFO_CAPS_JTAG
)) {
758 LOG_ERROR("CMSIS-DAP: JTAG not supported");
759 return ERROR_JTAG_DEVICE_ERROR
;
762 retval
= cmsis_dap_cmd_DAP_Connect(CONNECT_JTAG
);
763 if (retval
!= ERROR_OK
)
766 LOG_INFO("CMSIS-DAP: Interface Initialised (JTAG)");
769 retval
= cmsis_dap_get_version_info();
770 if (retval
!= ERROR_OK
)
773 /* INFO_ID_PKT_SZ - short */
774 retval
= cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_SZ
, &data
);
775 if (retval
!= ERROR_OK
)
778 if (data
[0] == 2) { /* short */
779 uint16_t pkt_sz
= data
[1] + (data
[2] << 8);
781 if (cmsis_dap_handle
->packet_size
!= pkt_sz
+ 1) {
782 /* reallocate buffer */
783 cmsis_dap_handle
->packet_size
= pkt_sz
+ 1;
784 cmsis_dap_handle
->packet_buffer
= realloc(cmsis_dap_handle
->packet_buffer
,
785 cmsis_dap_handle
->packet_size
);
786 if (cmsis_dap_handle
->packet_buffer
== NULL
) {
787 LOG_ERROR("unable to reallocate memory");
792 LOG_DEBUG("CMSIS-DAP: Packet Size = %" PRId16
, pkt_sz
);
795 /* INFO_ID_PKT_CNT - byte */
796 retval
= cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_CNT
, &data
);
797 if (retval
!= ERROR_OK
)
800 if (data
[0] == 1) { /* byte */
801 uint16_t pkt_cnt
= data
[1];
802 cmsis_dap_handle
->packet_count
= pkt_cnt
;
803 LOG_DEBUG("CMSIS-DAP: Packet Count = %" PRId16
, pkt_cnt
);
806 retval
= cmsis_dap_get_status();
807 if (retval
!= ERROR_OK
)
810 /* Now try to connect to the target
811 * TODO: This is all SWD only @ present */
812 retval
= cmsis_dap_cmd_DAP_SWJ_Clock(100); /* 100kHz */
813 if (retval
!= ERROR_OK
)
816 retval
= cmsis_dap_cmd_DAP_TFER_Configure(0, 64, 0);
817 if (retval
!= ERROR_OK
)
819 retval
= cmsis_dap_cmd_DAP_SWD_Configure(0x00);
820 if (retval
!= ERROR_OK
)
823 retval
= cmsis_dap_cmd_DAP_LED(0x03); /* Both LEDs on */
824 if (retval
!= ERROR_OK
)
827 /* support connecting with srst asserted */
828 enum reset_types jtag_reset_config
= jtag_get_reset_config();
830 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
831 if (jtag_reset_config
& RESET_SRST_NO_GATING
) {
832 retval
= cmsis_dap_cmd_DAP_SWJ_Pins(0, (1 << 7), 0, NULL
);
833 if (retval
!= ERROR_OK
)
835 LOG_INFO("Connecting under reset");
839 retval
= cmsis_dap_reset_link();
840 if (retval
!= ERROR_OK
)
843 cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */
845 LOG_INFO("CMSIS-DAP: Interface ready");
850 static int cmsis_dap_swd_init(uint8_t trn
)
854 DEBUG_IO("CMSIS-DAP: cmsis_dap_swd_init");
856 if (cmsis_dap_handle
== NULL
) {
859 retval
= cmsis_dap_usb_open();
860 if (retval
!= ERROR_OK
)
863 retval
= cmsis_dap_get_caps_info();
864 if (retval
!= ERROR_OK
)
868 if (!(cmsis_dap_handle
->caps
& INFO_CAPS_SWD
)) {
869 LOG_ERROR("CMSIS-DAP: SWD not supported");
870 return ERROR_JTAG_DEVICE_ERROR
;
873 retval
= cmsis_dap_cmd_DAP_Connect(CONNECT_SWD
);
874 if (retval
!= ERROR_OK
)
877 /* Add more setup here.??... */
879 LOG_INFO("CMSIS-DAP: Interface Initialised (SWD)");
883 static int cmsis_dap_quit(void)
885 cmsis_dap_cmd_DAP_Disconnect();
886 cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */
888 cmsis_dap_usb_close(cmsis_dap_handle
);
893 static void cmsis_dap_execute_reset(struct jtag_command
*cmd
)
895 int retval
= cmsis_dap_cmd_DAP_SWJ_Pins(cmd
->cmd
.reset
->srst
? 0 : (1 << 7), \
897 if (retval
!= ERROR_OK
)
898 LOG_ERROR("CMSIS-DAP: Interface reset failed");
901 static void cmsis_dap_execute_sleep(struct jtag_command
*cmd
)
904 int retval
= cmsis_dap_cmd_DAP_Delay(cmd
->cmd
.sleep
->us
);
905 if (retval
!= ERROR_OK
)
907 jtag_sleep(cmd
->cmd
.sleep
->us
);
910 static void cmsis_dap_execute_command(struct jtag_command
*cmd
)
914 cmsis_dap_execute_reset(cmd
);
917 cmsis_dap_execute_sleep(cmd
);
920 LOG_ERROR("BUG: unknown JTAG command type encountered");
925 static int cmsis_dap_execute_queue(void)
927 struct jtag_command
*cmd
= jtag_command_queue
;
929 while (cmd
!= NULL
) {
930 cmsis_dap_execute_command(cmd
);
937 static int cmsis_dap_speed(int speed
)
939 if (speed
> DAP_MAX_CLOCK
) {
940 LOG_INFO("reduce speed request: %dkHz to %dkHz maximum", speed
, DAP_MAX_CLOCK
);
941 speed
= DAP_MAX_CLOCK
;
945 LOG_INFO("RTCK not supported");
946 return ERROR_JTAG_NOT_IMPLEMENTED
;
949 return cmsis_dap_cmd_DAP_SWJ_Clock(speed
);
952 static int cmsis_dap_speed_div(int speed
, int *khz
)
958 static int cmsis_dap_khz(int khz
, int *jtag_speed
)
964 COMMAND_HANDLER(cmsis_dap_handle_info_command
)
966 if (cmsis_dap_get_version_info() == ERROR_OK
)
967 cmsis_dap_get_status();
972 COMMAND_HANDLER(cmsis_dap_handle_vid_pid_command
)
974 if (CMD_ARGC
> MAX_USB_IDS
* 2) {
975 LOG_WARNING("ignoring extra IDs in cmsis_dap_vid_pid "
976 "(maximum is %d pairs)", MAX_USB_IDS
);
977 CMD_ARGC
= MAX_USB_IDS
* 2;
979 if (CMD_ARGC
< 2 || (CMD_ARGC
& 1)) {
980 LOG_WARNING("incomplete cmsis_dap_vid_pid configuration directive");
982 return ERROR_COMMAND_SYNTAX_ERROR
;
983 /* remove the incomplete trailing id */
988 for (i
= 0; i
< CMD_ARGC
; i
+= 2) {
989 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[i
], cmsis_dap_vid
[i
>> 1]);
990 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[i
+ 1], cmsis_dap_pid
[i
>> 1]);
994 * Explicitly terminate, in case there are multiples instances of
997 cmsis_dap_vid
[i
>> 1] = cmsis_dap_pid
[i
>> 1] = 0;
1002 static const struct command_registration cmsis_dap_subcommand_handlers
[] = {
1005 .handler
= &cmsis_dap_handle_info_command
,
1006 .mode
= COMMAND_EXEC
,
1008 .help
= "show cmsis-dap info",
1010 COMMAND_REGISTRATION_DONE
1013 COMMAND_HANDLER(cmsis_dap_reset_command
)
1015 LOG_DEBUG("cmsis_dap_reset_command");
1019 COMMAND_HANDLER(cmsis_dap_jtag_command
)
1021 LOG_DEBUG("cmsis_dap_jtag_command");
1025 static const struct command_registration cmsis_dap_jtag_subcommand_handlers
[] = {
1028 .mode
= COMMAND_ANY
,
1029 .handler
= cmsis_dap_jtag_command
,
1034 .mode
= COMMAND_ANY
,
1035 .handler
= cmsis_dap_jtag_command
,
1039 .name
= "arp_init-reset",
1040 .mode
= COMMAND_ANY
,
1041 .handler
= cmsis_dap_reset_command
,
1045 .name
= "tapisenabled",
1046 .mode
= COMMAND_EXEC
,
1047 .jim_handler
= jim_jtag_tap_enabler
,
1050 .name
= "tapenable",
1051 .mode
= COMMAND_EXEC
,
1052 .jim_handler
= jim_jtag_tap_enabler
,
1055 .name
= "tapdisable",
1056 .mode
= COMMAND_EXEC
,
1057 .handler
= cmsis_dap_jtag_command
,
1061 .name
= "configure",
1062 .mode
= COMMAND_EXEC
,
1063 .handler
= cmsis_dap_jtag_command
,
1068 .mode
= COMMAND_EXEC
,
1069 .jim_handler
= jim_jtag_configure
,
1073 .mode
= COMMAND_ANY
,
1074 .handler
= cmsis_dap_jtag_command
,
1077 COMMAND_REGISTRATION_DONE
1080 static const struct command_registration cmsis_dap_command_handlers
[] = {
1082 .name
= "cmsis-dap",
1083 .mode
= COMMAND_ANY
,
1084 .help
= "perform CMSIS-DAP management",
1086 .chain
= cmsis_dap_subcommand_handlers
,
1089 .name
= "cmsis_dap_vid_pid",
1090 .handler
= &cmsis_dap_handle_vid_pid_command
,
1091 .mode
= COMMAND_CONFIG
,
1092 .help
= "the vendor ID and product ID of the CMSIS-DAP device",
1093 .usage
= "(vid pid)* ",
1096 /* this is currently a nasty hack so we get
1097 * reset working with non jtag interfaces */
1099 .mode
= COMMAND_ANY
,
1101 .chain
= cmsis_dap_jtag_subcommand_handlers
,
1103 COMMAND_REGISTRATION_DONE
1106 static const struct swd_driver cmsis_dap_swd_driver
= {
1107 .init
= cmsis_dap_swd_init
,
1108 .read_reg
= cmsis_dap_swd_read_reg
,
1109 .write_reg
= cmsis_dap_swd_write_reg
,
1110 .read_block
= cmsis_dap_swd_read_block
1113 const char *cmsis_dap_transport
[] = {"cmsis-dap", NULL
};
1115 struct jtag_interface cmsis_dap_interface
= {
1116 .name
= "cmsis-dap",
1117 .commands
= cmsis_dap_command_handlers
,
1118 .swd
= &cmsis_dap_swd_driver
,
1119 .transports
= cmsis_dap_transport
,
1121 .execute_queue
= cmsis_dap_execute_queue
,
1122 .speed
= cmsis_dap_speed
,
1123 .speed_div
= cmsis_dap_speed_div
,
1124 .khz
= cmsis_dap_khz
,
1125 .init
= cmsis_dap_init
,
1126 .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)