1 /***************************************************************************
3 * Copyright (C) 2012 by Spencer Oliver *
4 * spen@spen-soft.co.uk *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 ***************************************************************************/
24 /* project specific includes */
25 #include <helper/binarybuffer.h>
26 #include <jtag/interface.h>
27 #include <jtag/hla/hla_layout.h>
28 #include <jtag/hla/hla_transport.h>
29 #include <jtag/hla/hla_interface.h>
30 #include <target/target.h>
32 #include <target/cortex_m.h>
34 #include "libusb_helper.h"
36 #define ICDI_WRITE_ENDPOINT 0x02
37 #define ICDI_READ_ENDPOINT 0x83
39 #define ICDI_WRITE_TIMEOUT 1000
40 #define ICDI_READ_TIMEOUT 1000
41 #define ICDI_PACKET_SIZE 2048
43 #define PACKET_START "$"
44 #define PACKET_END "#"
46 struct icdi_usb_handle_s
{
47 struct libusb_device_handle
*usb_dev
;
53 uint32_t max_rw_packet
; /* max X packet (read/write memory) transfers */
56 static int icdi_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
57 uint32_t count
, uint8_t *buffer
);
58 static int icdi_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
59 uint32_t count
, const uint8_t *buffer
);
61 static int remote_escape_output(const char *buffer
, int len
, char *out_buf
, int *out_len
, int out_maxlen
)
63 int input_index
, output_index
;
67 for (input_index
= 0; input_index
< len
; input_index
++) {
69 char b
= buffer
[input_index
];
71 if (b
== '$' || b
== '#' || b
== '}' || b
== '*') {
72 /* These must be escaped. */
73 if (output_index
+ 2 > out_maxlen
)
75 out_buf
[output_index
++] = '}';
76 out_buf
[output_index
++] = b
^ 0x20;
78 if (output_index
+ 1 > out_maxlen
)
80 out_buf
[output_index
++] = b
;
84 *out_len
= input_index
;
88 static int remote_unescape_input(const char *buffer
, int len
, char *out_buf
, int out_maxlen
)
90 int input_index
, output_index
;
96 for (input_index
= 0; input_index
< len
; input_index
++) {
98 char b
= buffer
[input_index
];
100 if (output_index
+ 1 > out_maxlen
)
101 LOG_ERROR("Received too much data from the target.");
104 out_buf
[output_index
++] = b
^ 0x20;
109 out_buf
[output_index
++] = b
;
113 LOG_ERROR("Unmatched escape character in target response.");
118 static int icdi_send_packet(void *handle
, int len
)
120 unsigned char cksum
= 0;
121 struct icdi_usb_handle_s
*h
= handle
;
122 int result
, retry
= 0;
127 /* check we have a large enough buffer for checksum "#00" */
128 if (len
+ 3 > h
->max_packet
) {
129 LOG_ERROR("packet buffer too small");
133 /* calculate checksum - offset start of packet */
134 for (int i
= 1; i
< len
; i
++)
135 cksum
+= h
->write_buffer
[i
];
137 len
+= sprintf(&h
->write_buffer
[len
], PACKET_END
"%02x", cksum
);
139 #ifdef _DEBUG_USB_COMMS_
141 char ch
= h
->write_buffer
[1];
142 if (ch
== 'x' || ch
== 'X')
143 LOG_DEBUG("writing packet: <binary>");
145 memcpy(buffer
, h
->write_buffer
, len
>= 50 ? 50-1 : len
);
147 LOG_DEBUG("writing packet: %s", buffer
);
153 result
= libusb_bulk_transfer(h
->usb_dev
, ICDI_WRITE_ENDPOINT
, (unsigned char *)h
->write_buffer
, len
,
154 &transferred
, ICDI_WRITE_TIMEOUT
);
155 if (result
!= 0 || transferred
!= len
) {
156 LOG_DEBUG("Error TX Data %d", result
);
160 /* check that the client got the message ok, or shall we resend */
161 result
= libusb_bulk_transfer(h
->usb_dev
, ICDI_READ_ENDPOINT
, (unsigned char *)h
->read_buffer
, h
->max_packet
,
162 &transferred
, ICDI_READ_TIMEOUT
);
163 if (result
!= 0 || transferred
< 1) {
164 LOG_DEBUG("Error RX Data %d", result
);
168 #ifdef _DEBUG_USB_COMMS_
169 LOG_DEBUG("received reply: '%c' : count %d", h
->read_buffer
[0], transferred
);
172 if (h
->read_buffer
[0] == '-') {
173 LOG_DEBUG("Resending packet %d", ++retry
);
175 if (h
->read_buffer
[0] != '+')
176 LOG_DEBUG("Unexpected Reply from ICDI: %c", h
->read_buffer
[0]);
181 LOG_DEBUG("maximum nack retries attempted");
187 h
->read_count
= transferred
;
191 /* read reply from icdi */
192 result
= libusb_bulk_transfer(h
->usb_dev
, ICDI_READ_ENDPOINT
, (unsigned char *)h
->read_buffer
+ h
->read_count
,
193 h
->max_packet
- h
->read_count
, &transferred
, ICDI_READ_TIMEOUT
);
195 #ifdef _DEBUG_USB_COMMS_
196 LOG_DEBUG("received data: count %d", transferred
);
199 /* check for errors but retry for timeout */
202 if (result
== LIBUSB_ERROR_TIMEOUT
) {
203 LOG_DEBUG("Error RX timeout %d", result
);
205 LOG_DEBUG("Error RX Data %d", result
);
210 h
->read_count
+= transferred
;
212 /* we need to make sure we have a full packet, including checksum */
213 if (h
->read_count
> 5) {
215 /* check that we have received an packet delimiter
216 * we do not validate the checksum
217 * reply should contain $...#AA - so we check for # */
218 if (h
->read_buffer
[h
->read_count
- 3] == '#')
223 LOG_DEBUG("maximum data retries attempted");
231 static int icdi_send_cmd(void *handle
, const char *cmd
)
233 struct icdi_usb_handle_s
*h
= handle
;
235 int cmd_len
= snprintf(h
->write_buffer
, h
->max_packet
, PACKET_START
"%s", cmd
);
236 return icdi_send_packet(handle
, cmd_len
);
239 static int icdi_send_remote_cmd(void *handle
, const char *data
)
241 struct icdi_usb_handle_s
*h
= handle
;
243 size_t cmd_len
= sprintf(h
->write_buffer
, PACKET_START
"qRcmd,");
244 cmd_len
+= hexify(h
->write_buffer
+ cmd_len
, (const uint8_t *)data
,
245 strlen(data
), h
->max_packet
- cmd_len
);
247 return icdi_send_packet(handle
, cmd_len
);
250 static int icdi_get_cmd_result(void *handle
)
252 struct icdi_usb_handle_s
*h
= handle
;
259 ch
= h
->read_buffer
[offset
++];
260 if (offset
> h
->read_count
)
264 if (memcmp("OK", h
->read_buffer
+ offset
, 2) == 0)
267 if (h
->read_buffer
[offset
] == 'E') {
270 if (unhexify(&result
, h
->read_buffer
+ offset
+ 1, 1) != 1)
275 /* for now we assume everything else is ok */
279 static int icdi_usb_idcode(void *handle
, uint32_t *idcode
)
285 static int icdi_usb_write_debug_reg(void *handle
, uint32_t addr
, uint32_t val
)
288 /* REVISIT: There's no target pointer here so there's no way to use target_buffer_set_u32().
289 * I guess all supported chips are little-endian anyway. */
290 h_u32_to_le(buf
, val
);
291 return icdi_usb_write_mem(handle
, addr
, 4, 1, buf
);
294 static enum target_state
icdi_usb_state(void *handle
)
297 struct icdi_usb_handle_s
*h
= handle
;
301 result
= icdi_usb_read_mem(h
, DCB_DHCSR
, 4, 1, buf
);
302 if (result
!= ERROR_OK
)
303 return TARGET_UNKNOWN
;
305 /* REVISIT: There's no target pointer here so there's no way to use target_buffer_get_u32().
306 * I guess all supported chips are little-endian anyway. */
307 dhcsr
= le_to_h_u32(buf
);
309 return TARGET_HALTED
;
311 return TARGET_RUNNING
;
314 static int icdi_usb_version(void *handle
)
316 struct icdi_usb_handle_s
*h
= handle
;
320 /* get info about icdi */
321 int result
= icdi_send_remote_cmd(handle
, "version");
322 if (result
!= ERROR_OK
)
325 if (h
->read_count
< 8) {
326 LOG_ERROR("Invalid Reply Received");
331 if (unhexify((uint8_t *)version
, h
->read_buffer
+ 2, 4) != 4) {
332 LOG_WARNING("unable to get ICDI version");
336 /* null terminate and print info */
339 LOG_INFO("ICDI Firmware version: %s", version
);
344 static int icdi_usb_query(void *handle
)
348 struct icdi_usb_handle_s
*h
= handle
;
350 result
= icdi_send_cmd(handle
, "qSupported");
351 if (result
!= ERROR_OK
)
355 result
= icdi_get_cmd_result(handle
);
356 if (result
!= ERROR_OK
) {
357 LOG_ERROR("query supported failed: 0x%x", result
);
361 /* from this we can get the max packet supported */
363 /* query packet buffer size */
364 char *offset
= strstr(h
->read_buffer
, "PacketSize");
369 max_packet
= strtol(offset
+ 11, &separator
, 16);
371 LOG_ERROR("invalid max packet, using defaults");
373 h
->max_packet
= max_packet
;
374 LOG_DEBUG("max packet supported : %i bytes", h
->max_packet
);
378 /* if required re allocate packet buffer */
379 if (h
->max_packet
!= ICDI_PACKET_SIZE
) {
380 h
->read_buffer
= realloc(h
->read_buffer
, h
->max_packet
);
381 h
->write_buffer
= realloc(h
->write_buffer
, h
->max_packet
);
382 if (h
->read_buffer
== 0 || h
->write_buffer
== 0) {
383 LOG_ERROR("unable to reallocate memory");
388 /* set extended mode */
389 result
= icdi_send_cmd(handle
, "!");
390 if (result
!= ERROR_OK
)
394 result
= icdi_get_cmd_result(handle
);
395 if (result
!= ERROR_OK
) {
396 LOG_ERROR("unable to enable extended mode: 0x%x", result
);
403 static int icdi_usb_reset(void *handle
)
405 /* we do this in hla_target.c */
409 static int icdi_usb_assert_srst(void *handle
, int srst
)
411 /* TODO not supported yet */
412 return ERROR_COMMAND_NOTFOUND
;
415 static int icdi_usb_run(void *handle
)
419 /* resume target at current address */
420 result
= icdi_send_cmd(handle
, "c");
421 if (result
!= ERROR_OK
)
425 result
= icdi_get_cmd_result(handle
);
426 if (result
!= ERROR_OK
) {
427 LOG_ERROR("continue failed: 0x%x", result
);
434 static int icdi_usb_halt(void *handle
)
438 /* this query halts the target ?? */
439 result
= icdi_send_cmd(handle
, "?");
440 if (result
!= ERROR_OK
)
444 result
= icdi_get_cmd_result(handle
);
445 if (result
!= ERROR_OK
) {
446 LOG_ERROR("halt failed: 0x%x", result
);
453 static int icdi_usb_step(void *handle
)
457 /* step target at current address */
458 result
= icdi_send_cmd(handle
, "s");
459 if (result
!= ERROR_OK
)
463 result
= icdi_get_cmd_result(handle
);
464 if (result
!= ERROR_OK
) {
465 LOG_ERROR("step failed: 0x%x", result
);
472 static int icdi_usb_read_regs(void *handle
)
474 /* currently unsupported */
478 static int icdi_usb_read_reg(void *handle
, unsigned int regsel
, uint32_t *val
)
481 struct icdi_usb_handle_s
*h
= handle
;
484 snprintf(cmd
, sizeof(cmd
), "p%x", regsel
);
485 result
= icdi_send_cmd(handle
, cmd
);
486 if (result
!= ERROR_OK
)
490 result
= icdi_get_cmd_result(handle
);
491 if (result
!= ERROR_OK
) {
492 LOG_ERROR("register read failed: 0x%x", result
);
498 if (unhexify(buf
, h
->read_buffer
+ 2, 4) != 4) {
499 LOG_ERROR("failed to convert result");
502 *val
= le_to_h_u32(buf
);
507 static int icdi_usb_write_reg(void *handle
, unsigned int regsel
, uint32_t val
)
512 h_u32_to_le(buf
, val
);
514 int cmd_len
= snprintf(cmd
, sizeof(cmd
), "P%x=", regsel
);
515 hexify(cmd
+ cmd_len
, buf
, 4, sizeof(cmd
));
517 result
= icdi_send_cmd(handle
, cmd
);
518 if (result
!= ERROR_OK
)
522 result
= icdi_get_cmd_result(handle
);
523 if (result
!= ERROR_OK
) {
524 LOG_ERROR("register write failed: 0x%x", result
);
531 static int icdi_usb_read_mem_int(void *handle
, uint32_t addr
, uint32_t len
, uint8_t *buffer
)
534 struct icdi_usb_handle_s
*h
= handle
;
537 snprintf(cmd
, sizeof(cmd
), "x%" PRIx32
",%" PRIx32
, addr
, len
);
538 result
= icdi_send_cmd(handle
, cmd
);
539 if (result
!= ERROR_OK
)
543 result
= icdi_get_cmd_result(handle
);
544 if (result
!= ERROR_OK
) {
545 LOG_ERROR("memory read failed: 0x%x", result
);
550 int read_len
= remote_unescape_input(h
->read_buffer
+ 5, h
->read_count
- 8, (char *)buffer
, len
);
551 if (read_len
!= (int)len
) {
552 LOG_ERROR("read more bytes than expected: actual 0x%x expected 0x%" PRIx32
, read_len
, len
);
559 static int icdi_usb_write_mem_int(void *handle
, uint32_t addr
, uint32_t len
, const uint8_t *buffer
)
562 struct icdi_usb_handle_s
*h
= handle
;
564 size_t cmd_len
= snprintf(h
->write_buffer
, h
->max_packet
, PACKET_START
"X%" PRIx32
",%" PRIx32
":", addr
, len
);
567 cmd_len
+= remote_escape_output((const char *)buffer
, len
, h
->write_buffer
+ cmd_len
,
568 &out_len
, h
->max_packet
- cmd_len
);
570 if (out_len
< (int)len
) {
571 /* for now issue a error as we have no way of allocating a larger buffer */
572 LOG_ERROR("memory buffer too small: requires 0x%x actual 0x%" PRIx32
, out_len
, len
);
576 result
= icdi_send_packet(handle
, cmd_len
);
577 if (result
!= ERROR_OK
)
581 result
= icdi_get_cmd_result(handle
);
582 if (result
!= ERROR_OK
) {
583 LOG_ERROR("memory write failed: 0x%x", result
);
590 static int icdi_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
591 uint32_t count
, uint8_t *buffer
)
593 int retval
= ERROR_OK
;
594 struct icdi_usb_handle_s
*h
= handle
;
595 uint32_t bytes_remaining
;
597 /* calculate byte count */
602 bytes_remaining
= h
->max_rw_packet
;
603 if (count
< bytes_remaining
)
604 bytes_remaining
= count
;
606 retval
= icdi_usb_read_mem_int(handle
, addr
, bytes_remaining
, buffer
);
607 if (retval
!= ERROR_OK
)
610 buffer
+= bytes_remaining
;
611 addr
+= bytes_remaining
;
612 count
-= bytes_remaining
;
618 static int icdi_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
619 uint32_t count
, const uint8_t *buffer
)
621 int retval
= ERROR_OK
;
622 struct icdi_usb_handle_s
*h
= handle
;
623 uint32_t bytes_remaining
;
625 /* calculate byte count */
630 bytes_remaining
= h
->max_rw_packet
;
631 if (count
< bytes_remaining
)
632 bytes_remaining
= count
;
634 retval
= icdi_usb_write_mem_int(handle
, addr
, bytes_remaining
, buffer
);
635 if (retval
!= ERROR_OK
)
638 buffer
+= bytes_remaining
;
639 addr
+= bytes_remaining
;
640 count
-= bytes_remaining
;
646 static int icdi_usb_override_target(const char *targetname
)
648 return !strcmp(targetname
, "cortex_m");
651 static int icdi_usb_close(void *handle
)
653 struct icdi_usb_handle_s
*h
= handle
;
659 jtag_libusb_close(h
->usb_dev
);
661 free(h
->read_buffer
);
662 free(h
->write_buffer
);
667 static int icdi_usb_open(struct hl_interface_param_s
*param
, void **fd
)
669 /* TODO: Convert remaining libusb_ calls to jtag_libusb_ */
671 struct icdi_usb_handle_s
*h
;
673 LOG_DEBUG("icdi_usb_open");
675 h
= calloc(1, sizeof(struct icdi_usb_handle_s
));
678 LOG_ERROR("unable to allocate memory");
682 for (uint8_t i
= 0; param
->vid
[i
] && param
->pid
[i
]; ++i
)
683 LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", param
->transport
,
684 param
->vid
[i
], param
->pid
[i
], param
->serial
? param
->serial
: "");
686 /* TI (Stellaris) ICDI provides its serial number in the USB descriptor;
687 no need to provide a callback here. */
688 jtag_libusb_open(param
->vid
, param
->pid
, param
->serial
, &h
->usb_dev
, NULL
);
691 LOG_ERROR("open failed");
695 if (libusb_claim_interface(h
->usb_dev
, 2)) {
696 LOG_DEBUG("claim interface failed");
700 /* check if mode is supported */
703 switch (param
->transport
) {
705 /* TODO place holder as swd is not currently supported */
706 case HL_TRANSPORT_SWD
:
708 case HL_TRANSPORT_JTAG
:
715 if (retval
!= ERROR_OK
) {
716 LOG_ERROR("mode (transport) not supported by device");
720 /* allocate buffer */
721 h
->read_buffer
= malloc(ICDI_PACKET_SIZE
);
722 h
->write_buffer
= malloc(ICDI_PACKET_SIZE
);
723 h
->max_packet
= ICDI_PACKET_SIZE
;
725 if (h
->read_buffer
== 0 || h
->write_buffer
== 0) {
726 LOG_DEBUG("malloc failed");
730 /* query icdi version etc */
731 retval
= icdi_usb_version(h
);
732 if (retval
!= ERROR_OK
)
735 /* query icdi support */
736 retval
= icdi_usb_query(h
);
737 if (retval
!= ERROR_OK
)
742 /* set the max target read/write buffer in bytes
743 * as we are using gdb binary packets to transfer memory we have to
744 * reserve half the buffer for any possible escape chars plus
745 * at least 64 bytes for the gdb packet header */
746 h
->max_rw_packet
= (((h
->max_packet
- 64) / 4) * 4) / 2;
756 struct hl_layout_api_s icdi_usb_layout_api
= {
757 .open
= icdi_usb_open
,
758 .close
= icdi_usb_close
,
759 .idcode
= icdi_usb_idcode
,
760 .state
= icdi_usb_state
,
761 .reset
= icdi_usb_reset
,
762 .assert_srst
= icdi_usb_assert_srst
,
764 .halt
= icdi_usb_halt
,
765 .step
= icdi_usb_step
,
766 .read_regs
= icdi_usb_read_regs
,
767 .read_reg
= icdi_usb_read_reg
,
768 .write_reg
= icdi_usb_write_reg
,
769 .read_mem
= icdi_usb_read_mem
,
770 .write_mem
= icdi_usb_write_mem
,
771 .write_debug_reg
= icdi_usb_write_debug_reg
,
772 .override_target
= icdi_usb_override_target
,
773 .custom_command
= icdi_send_remote_cmd
,
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)