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>
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 libusb_context
*usb_ctx
;
48 libusb_device_handle
*usb_dev
;
54 uint32_t max_rw_packet
; /* max X packet (read/write memory) transfers */
57 static int icdi_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
58 uint32_t count
, uint8_t *buffer
);
59 static int icdi_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
60 uint32_t count
, const uint8_t *buffer
);
62 static int remote_escape_output(const char *buffer
, int len
, char *out_buf
, int *out_len
, int out_maxlen
)
64 int input_index
, output_index
;
68 for (input_index
= 0; input_index
< len
; input_index
++) {
70 char b
= buffer
[input_index
];
72 if (b
== '$' || b
== '#' || b
== '}' || b
== '*') {
73 /* These must be escaped. */
74 if (output_index
+ 2 > out_maxlen
)
76 out_buf
[output_index
++] = '}';
77 out_buf
[output_index
++] = b
^ 0x20;
79 if (output_index
+ 1 > out_maxlen
)
81 out_buf
[output_index
++] = b
;
85 *out_len
= input_index
;
89 static int remote_unescape_input(const char *buffer
, int len
, char *out_buf
, int out_maxlen
)
91 int input_index
, output_index
;
97 for (input_index
= 0; input_index
< len
; input_index
++) {
99 char b
= buffer
[input_index
];
101 if (output_index
+ 1 > out_maxlen
)
102 LOG_ERROR("Received too much data from the target.");
105 out_buf
[output_index
++] = b
^ 0x20;
110 out_buf
[output_index
++] = b
;
114 LOG_ERROR("Unmatched escape character in target response.");
119 static int icdi_send_packet(void *handle
, int len
)
121 unsigned char cksum
= 0;
122 struct icdi_usb_handle_s
*h
= handle
;
123 int result
, retry
= 0;
126 assert(handle
!= NULL
);
128 /* check we have a large enough buffer for checksum "#00" */
129 if (len
+ 3 > h
->max_packet
) {
130 LOG_ERROR("packet buffer too small");
134 /* calculate checksum - offset start of packet */
135 for (int i
= 1; i
< len
; i
++)
136 cksum
+= h
->write_buffer
[i
];
138 len
+= sprintf(&h
->write_buffer
[len
], PACKET_END
"%02x", cksum
);
140 #ifdef _DEBUG_USB_COMMS_
142 char ch
= h
->write_buffer
[1];
143 if (ch
== 'x' || ch
== 'X')
144 LOG_DEBUG("writing packet: <binary>");
146 memcpy(buffer
, h
->write_buffer
, len
>= 50 ? 50-1 : len
);
148 LOG_DEBUG("writing packet: %s", buffer
);
154 result
= libusb_bulk_transfer(h
->usb_dev
, ICDI_WRITE_ENDPOINT
, (unsigned char *)h
->write_buffer
, len
,
155 &transferred
, ICDI_WRITE_TIMEOUT
);
156 if (result
!= 0 || transferred
!= len
) {
157 LOG_DEBUG("Error TX Data %d", result
);
161 /* check that the client got the message ok, or shall we resend */
162 result
= libusb_bulk_transfer(h
->usb_dev
, ICDI_READ_ENDPOINT
, (unsigned char *)h
->read_buffer
, h
->max_packet
,
163 &transferred
, ICDI_READ_TIMEOUT
);
164 if (result
!= 0 || transferred
< 1) {
165 LOG_DEBUG("Error RX Data %d", result
);
169 #ifdef _DEBUG_USB_COMMS_
170 LOG_DEBUG("received reply: '%c' : count %d", h
->read_buffer
[0], transferred
);
173 if (h
->read_buffer
[0] == '-') {
174 LOG_DEBUG("Resending packet %d", ++retry
);
176 if (h
->read_buffer
[0] != '+')
177 LOG_DEBUG("Unexpected Reply from ICDI: %c", h
->read_buffer
[0]);
182 LOG_DEBUG("maximum nack retries attempted");
188 h
->read_count
= transferred
;
192 /* read reply from icdi */
193 result
= libusb_bulk_transfer(h
->usb_dev
, ICDI_READ_ENDPOINT
, (unsigned char *)h
->read_buffer
+ h
->read_count
,
194 h
->max_packet
- h
->read_count
, &transferred
, ICDI_READ_TIMEOUT
);
196 #ifdef _DEBUG_USB_COMMS_
197 LOG_DEBUG("received data: count %d", transferred
);
200 /* check for errors but retry for timeout */
203 if (result
== LIBUSB_ERROR_TIMEOUT
) {
204 LOG_DEBUG("Error RX timeout %d", result
);
206 LOG_DEBUG("Error RX Data %d", result
);
211 h
->read_count
+= transferred
;
213 /* we need to make sure we have a full packet, including checksum */
214 if (h
->read_count
> 5) {
216 /* check that we have received an packet delimiter
217 * we do not validate the checksum
218 * reply should contain $...#AA - so we check for # */
219 if (h
->read_buffer
[h
->read_count
- 3] == '#')
224 LOG_DEBUG("maximum data retries attempted");
232 static int icdi_send_cmd(void *handle
, const char *cmd
)
234 struct icdi_usb_handle_s
*h
= handle
;
236 int cmd_len
= snprintf(h
->write_buffer
, h
->max_packet
, PACKET_START
"%s", cmd
);
237 return icdi_send_packet(handle
, cmd_len
);
240 static int icdi_send_remote_cmd(void *handle
, const char *data
)
242 struct icdi_usb_handle_s
*h
= handle
;
244 size_t cmd_len
= sprintf(h
->write_buffer
, PACKET_START
"qRcmd,");
245 cmd_len
+= hexify(h
->write_buffer
+ cmd_len
, (const uint8_t *)data
,
246 strlen(data
), h
->max_packet
- cmd_len
);
248 return icdi_send_packet(handle
, cmd_len
);
251 static int icdi_get_cmd_result(void *handle
)
253 struct icdi_usb_handle_s
*h
= handle
;
257 assert(handle
!= NULL
);
260 ch
= h
->read_buffer
[offset
++];
261 if (offset
> h
->read_count
)
265 if (memcmp("OK", h
->read_buffer
+ offset
, 2) == 0)
268 if (h
->read_buffer
[offset
] == 'E') {
271 if (unhexify(&result
, h
->read_buffer
+ offset
+ 1, 1) != 1)
276 /* for now we assume everything else is ok */
280 static int icdi_usb_idcode(void *handle
, uint32_t *idcode
)
286 static int icdi_usb_write_debug_reg(void *handle
, uint32_t addr
, uint32_t val
)
289 /* REVISIT: There's no target pointer here so there's no way to use target_buffer_set_u32().
290 * I guess all supported chips are little-endian anyway. */
291 h_u32_to_le(buf
, val
);
292 return icdi_usb_write_mem(handle
, addr
, 4, 1, buf
);
295 static enum target_state
icdi_usb_state(void *handle
)
298 struct icdi_usb_handle_s
*h
= handle
;
302 result
= icdi_usb_read_mem(h
, DCB_DHCSR
, 4, 1, buf
);
303 if (result
!= ERROR_OK
)
304 return TARGET_UNKNOWN
;
306 /* REVISIT: There's no target pointer here so there's no way to use target_buffer_get_u32().
307 * I guess all supported chips are little-endian anyway. */
308 dhcsr
= le_to_h_u32(buf
);
310 return TARGET_HALTED
;
312 return TARGET_RUNNING
;
315 static int icdi_usb_version(void *handle
)
317 struct icdi_usb_handle_s
*h
= handle
;
321 /* get info about icdi */
322 int result
= icdi_send_remote_cmd(handle
, "version");
323 if (result
!= ERROR_OK
)
326 if (h
->read_count
< 8) {
327 LOG_ERROR("Invalid Reply Received");
332 if (unhexify((uint8_t *)version
, h
->read_buffer
+ 2, 4) != 4) {
333 LOG_WARNING("unable to get ICDI version");
337 /* null terminate and print info */
340 LOG_INFO("ICDI Firmware version: %s", version
);
345 static int icdi_usb_query(void *handle
)
349 struct icdi_usb_handle_s
*h
= handle
;
351 result
= icdi_send_cmd(handle
, "qSupported");
352 if (result
!= ERROR_OK
)
356 result
= icdi_get_cmd_result(handle
);
357 if (result
!= ERROR_OK
) {
358 LOG_ERROR("query supported failed: 0x%x", result
);
362 /* from this we can get the max packet supported */
364 /* query packet buffer size */
365 char *offset
= strstr(h
->read_buffer
, "PacketSize");
370 max_packet
= strtol(offset
+ 11, &separator
, 16);
372 LOG_ERROR("invalid max packet, using defaults");
374 h
->max_packet
= max_packet
;
375 LOG_DEBUG("max packet supported : %i bytes", h
->max_packet
);
379 /* if required re allocate packet buffer */
380 if (h
->max_packet
!= ICDI_PACKET_SIZE
) {
381 h
->read_buffer
= realloc(h
->read_buffer
, h
->max_packet
);
382 h
->write_buffer
= realloc(h
->write_buffer
, h
->max_packet
);
383 if (h
->read_buffer
== 0 || h
->write_buffer
== 0) {
384 LOG_ERROR("unable to reallocate memory");
389 /* set extended mode */
390 result
= icdi_send_cmd(handle
, "!");
391 if (result
!= ERROR_OK
)
395 result
= icdi_get_cmd_result(handle
);
396 if (result
!= ERROR_OK
) {
397 LOG_ERROR("unable to enable extended mode: 0x%x", result
);
404 static int icdi_usb_reset(void *handle
)
406 /* we do this in hla_target.c */
410 static int icdi_usb_assert_srst(void *handle
, int srst
)
412 /* TODO not supported yet */
413 return ERROR_COMMAND_NOTFOUND
;
416 static int icdi_usb_run(void *handle
)
420 /* resume target at current address */
421 result
= icdi_send_cmd(handle
, "c");
422 if (result
!= ERROR_OK
)
426 result
= icdi_get_cmd_result(handle
);
427 if (result
!= ERROR_OK
) {
428 LOG_ERROR("continue failed: 0x%x", result
);
435 static int icdi_usb_halt(void *handle
)
439 /* this query halts the target ?? */
440 result
= icdi_send_cmd(handle
, "?");
441 if (result
!= ERROR_OK
)
445 result
= icdi_get_cmd_result(handle
);
446 if (result
!= ERROR_OK
) {
447 LOG_ERROR("halt failed: 0x%x", result
);
454 static int icdi_usb_step(void *handle
)
458 /* step target at current address */
459 result
= icdi_send_cmd(handle
, "s");
460 if (result
!= ERROR_OK
)
464 result
= icdi_get_cmd_result(handle
);
465 if (result
!= ERROR_OK
) {
466 LOG_ERROR("step failed: 0x%x", result
);
473 static int icdi_usb_read_regs(void *handle
)
475 /* currently unsupported */
479 static int icdi_usb_read_reg(void *handle
, int num
, uint32_t *val
)
482 struct icdi_usb_handle_s
*h
= handle
;
485 snprintf(cmd
, sizeof(cmd
), "p%x", num
);
486 result
= icdi_send_cmd(handle
, cmd
);
487 if (result
!= ERROR_OK
)
491 result
= icdi_get_cmd_result(handle
);
492 if (result
!= ERROR_OK
) {
493 LOG_ERROR("register read failed: 0x%x", result
);
499 if (unhexify(buf
, h
->read_buffer
+ 2, 4) != 4) {
500 LOG_ERROR("failed to convert result");
503 *val
= le_to_h_u32(buf
);
508 static int icdi_usb_write_reg(void *handle
, int num
, uint32_t val
)
513 h_u32_to_le(buf
, val
);
515 int cmd_len
= snprintf(cmd
, sizeof(cmd
), "P%x=", num
);
516 hexify(cmd
+ cmd_len
, buf
, 4, sizeof(cmd
));
518 result
= icdi_send_cmd(handle
, cmd
);
519 if (result
!= ERROR_OK
)
523 result
= icdi_get_cmd_result(handle
);
524 if (result
!= ERROR_OK
) {
525 LOG_ERROR("register write failed: 0x%x", result
);
532 static int icdi_usb_read_mem_int(void *handle
, uint32_t addr
, uint32_t len
, uint8_t *buffer
)
535 struct icdi_usb_handle_s
*h
= handle
;
538 snprintf(cmd
, sizeof(cmd
), "x%" PRIx32
",%" PRIx32
, addr
, len
);
539 result
= icdi_send_cmd(handle
, cmd
);
540 if (result
!= ERROR_OK
)
544 result
= icdi_get_cmd_result(handle
);
545 if (result
!= ERROR_OK
) {
546 LOG_ERROR("memory read failed: 0x%x", result
);
551 int read_len
= remote_unescape_input(h
->read_buffer
+ 5, h
->read_count
- 8, (char *)buffer
, len
);
552 if (read_len
!= (int)len
) {
553 LOG_ERROR("read more bytes than expected: actual 0x%x expected 0x%" PRIx32
, read_len
, len
);
560 static int icdi_usb_write_mem_int(void *handle
, uint32_t addr
, uint32_t len
, const uint8_t *buffer
)
563 struct icdi_usb_handle_s
*h
= handle
;
565 size_t cmd_len
= snprintf(h
->write_buffer
, h
->max_packet
, PACKET_START
"X%" PRIx32
",%" PRIx32
":", addr
, len
);
568 cmd_len
+= remote_escape_output((const char *)buffer
, len
, h
->write_buffer
+ cmd_len
,
569 &out_len
, h
->max_packet
- cmd_len
);
571 if (out_len
< (int)len
) {
572 /* for now issue a error as we have no way of allocating a larger buffer */
573 LOG_ERROR("memory buffer too small: requires 0x%x actual 0x%" PRIx32
, out_len
, len
);
577 result
= icdi_send_packet(handle
, cmd_len
);
578 if (result
!= ERROR_OK
)
582 result
= icdi_get_cmd_result(handle
);
583 if (result
!= ERROR_OK
) {
584 LOG_ERROR("memory write failed: 0x%x", result
);
591 static int icdi_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
592 uint32_t count
, uint8_t *buffer
)
594 int retval
= ERROR_OK
;
595 struct icdi_usb_handle_s
*h
= handle
;
596 uint32_t bytes_remaining
;
598 /* calculate byte count */
603 bytes_remaining
= h
->max_rw_packet
;
604 if (count
< bytes_remaining
)
605 bytes_remaining
= count
;
607 retval
= icdi_usb_read_mem_int(handle
, addr
, bytes_remaining
, buffer
);
608 if (retval
!= ERROR_OK
)
611 buffer
+= bytes_remaining
;
612 addr
+= bytes_remaining
;
613 count
-= bytes_remaining
;
619 static int icdi_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
620 uint32_t count
, const uint8_t *buffer
)
622 int retval
= ERROR_OK
;
623 struct icdi_usb_handle_s
*h
= handle
;
624 uint32_t bytes_remaining
;
626 /* calculate byte count */
631 bytes_remaining
= h
->max_rw_packet
;
632 if (count
< bytes_remaining
)
633 bytes_remaining
= count
;
635 retval
= icdi_usb_write_mem_int(handle
, addr
, bytes_remaining
, buffer
);
636 if (retval
!= ERROR_OK
)
639 buffer
+= bytes_remaining
;
640 addr
+= bytes_remaining
;
641 count
-= bytes_remaining
;
647 static int icdi_usb_override_target(const char *targetname
)
649 return !strcmp(targetname
, "cortex_m");
652 static int icdi_usb_close(void *handle
)
654 struct icdi_usb_handle_s
*h
= handle
;
660 libusb_close(h
->usb_dev
);
663 libusb_exit(h
->usb_ctx
);
666 free(h
->read_buffer
);
669 free(h
->write_buffer
);
676 static int icdi_usb_open(struct hl_interface_param_s
*param
, void **fd
)
679 struct icdi_usb_handle_s
*h
;
681 LOG_DEBUG("icdi_usb_open");
683 h
= calloc(1, sizeof(struct icdi_usb_handle_s
));
686 LOG_ERROR("unable to allocate memory");
690 LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param
->transport
,
691 param
->vid
[0], param
->pid
[0]);
693 /* TODO: convert libusb_ calls to jtag_libusb_ */
695 LOG_WARNING("Bad configuration: 'hla_vid_pid' command does not accept more than one VID PID pair on ti-icdi!");
697 if (libusb_init(&h
->usb_ctx
) != 0) {
698 LOG_ERROR("libusb init failed");
702 h
->usb_dev
= libusb_open_device_with_vid_pid(h
->usb_ctx
, param
->vid
[0], param
->pid
[0]);
704 LOG_ERROR("open failed");
708 if (libusb_claim_interface(h
->usb_dev
, 2)) {
709 LOG_DEBUG("claim interface failed");
713 /* check if mode is supported */
716 switch (param
->transport
) {
718 /* TODO place holder as swd is not currently supported */
719 case HL_TRANSPORT_SWD
:
721 case HL_TRANSPORT_JTAG
:
728 if (retval
!= ERROR_OK
) {
729 LOG_ERROR("mode (transport) not supported by device");
733 /* allocate buffer */
734 h
->read_buffer
= malloc(ICDI_PACKET_SIZE
);
735 h
->write_buffer
= malloc(ICDI_PACKET_SIZE
);
736 h
->max_packet
= ICDI_PACKET_SIZE
;
738 if (h
->read_buffer
== 0 || h
->write_buffer
== 0) {
739 LOG_DEBUG("malloc failed");
743 /* query icdi version etc */
744 retval
= icdi_usb_version(h
);
745 if (retval
!= ERROR_OK
)
748 /* query icdi support */
749 retval
= icdi_usb_query(h
);
750 if (retval
!= ERROR_OK
)
755 /* set the max target read/write buffer in bytes
756 * as we are using gdb binary packets to transfer memory we have to
757 * reserve half the buffer for any possible escape chars plus
758 * at least 64 bytes for the gdb packet header */
759 h
->max_rw_packet
= (((h
->max_packet
- 64) / 4) * 4) / 2;
769 struct hl_layout_api_s icdi_usb_layout_api
= {
770 .open
= icdi_usb_open
,
771 .close
= icdi_usb_close
,
772 .idcode
= icdi_usb_idcode
,
773 .state
= icdi_usb_state
,
774 .reset
= icdi_usb_reset
,
775 .assert_srst
= icdi_usb_assert_srst
,
777 .halt
= icdi_usb_halt
,
778 .step
= icdi_usb_step
,
779 .read_regs
= icdi_usb_read_regs
,
780 .read_reg
= icdi_usb_read_reg
,
781 .write_reg
= icdi_usb_write_reg
,
782 .read_mem
= icdi_usb_read_mem
,
783 .write_mem
= icdi_usb_write_mem
,
784 .write_debug_reg
= icdi_usb_write_debug_reg
,
785 .override_target
= icdi_usb_override_target
,
786 .custom_command
= icdi_send_remote_cmd
,