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, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
20 ***************************************************************************/
26 /* project specific includes */
27 #include <helper/binarybuffer.h>
28 #include <jtag/interface.h>
29 #include <jtag/hla/hla_layout.h>
30 #include <jtag/hla/hla_transport.h>
31 #include <jtag/hla/hla_interface.h>
32 #include <target/target.h>
34 #include <target/cortex_m.h>
38 #define ICDI_WRITE_ENDPOINT 0x02
39 #define ICDI_READ_ENDPOINT 0x83
41 #define ICDI_WRITE_TIMEOUT 1000
42 #define ICDI_READ_TIMEOUT 1000
43 #define ICDI_PACKET_SIZE 2048
45 #define PACKET_START "$"
46 #define PACKET_END "#"
48 struct icdi_usb_handle_s
{
49 libusb_context
*usb_ctx
;
50 libusb_device_handle
*usb_dev
;
58 static int icdi_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
59 uint32_t count
, uint8_t *buffer
);
60 static int icdi_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
61 uint32_t count
, const uint8_t *buffer
);
63 static int remote_escape_output(const char *buffer
, int len
, char *out_buf
, int *out_len
, int out_maxlen
)
65 int input_index
, output_index
;
69 for (input_index
= 0; input_index
< len
; input_index
++) {
71 char b
= buffer
[input_index
];
73 if (b
== '$' || b
== '#' || b
== '}' || b
== '*') {
74 /* These must be escaped. */
75 if (output_index
+ 2 > out_maxlen
)
77 out_buf
[output_index
++] = '}';
78 out_buf
[output_index
++] = b
^ 0x20;
80 if (output_index
+ 1 > out_maxlen
)
82 out_buf
[output_index
++] = b
;
86 *out_len
= input_index
;
90 static int remote_unescape_input(const char *buffer
, int len
, char *out_buf
, int out_maxlen
)
92 int input_index
, output_index
;
98 for (input_index
= 0; input_index
< len
; input_index
++) {
100 char b
= buffer
[input_index
];
102 if (output_index
+ 1 > out_maxlen
)
103 LOG_ERROR("Received too much data from the target.");
106 out_buf
[output_index
++] = b
^ 0x20;
111 out_buf
[output_index
++] = b
;
115 LOG_ERROR("Unmatched escape character in target response.");
120 static int icdi_send_packet(void *handle
, int len
)
122 unsigned char cksum
= 0;
123 struct icdi_usb_handle_s
*h
;
124 int result
, retry
= 0;
127 assert(handle
!= NULL
);
128 h
= (struct icdi_usb_handle_s
*)handle
;
130 /* check we have a large enough buffer for checksum "#00" */
131 if (len
+ 3 > h
->max_packet
) {
132 LOG_ERROR("packet buffer too small");
136 /* calculate checksum - offset start of packet */
137 for (int i
= 1; i
< len
; i
++)
138 cksum
+= h
->write_buffer
[i
];
140 len
+= sprintf(&h
->write_buffer
[len
], PACKET_END
"%02x", cksum
);
142 #ifdef _DEBUG_USB_COMMS_
144 char ch
= h
->write_buffer
[1];
145 if (ch
== 'x' || ch
== 'X')
146 LOG_DEBUG("writing packet: <binary>");
148 memcpy(buffer
, h
->write_buffer
, len
>= 50 ? 50-1 : len
);
150 LOG_DEBUG("writing packet: %s", buffer
);
156 result
= libusb_bulk_transfer(h
->usb_dev
, ICDI_WRITE_ENDPOINT
, (unsigned char *)h
->write_buffer
, len
,
157 &transferred
, ICDI_WRITE_TIMEOUT
);
158 if (result
!= 0 || transferred
!= len
) {
159 LOG_DEBUG("Error TX Data %d", result
);
163 /* check that the client got the message ok, or shall we resend */
164 result
= libusb_bulk_transfer(h
->usb_dev
, ICDI_READ_ENDPOINT
, (unsigned char *)h
->read_buffer
, h
->max_packet
,
165 &transferred
, ICDI_READ_TIMEOUT
);
166 if (result
!= 0 || transferred
< 1) {
167 LOG_DEBUG("Error RX Data %d", result
);
171 #ifdef _DEBUG_USB_COMMS_
172 LOG_DEBUG("received reply: '%c' : count %d", h
->read_buffer
[0], transferred
);
175 if (h
->read_buffer
[0] == '-') {
176 LOG_DEBUG("Resending packet %d", ++retry
);
178 if (h
->read_buffer
[0] != '+')
179 LOG_DEBUG("Unexpected Reply from ICDI: %c", h
->read_buffer
[0]);
184 LOG_DEBUG("maximum nack retries attempted");
190 h
->read_count
= transferred
;
194 /* read reply from icdi */
195 result
= libusb_bulk_transfer(h
->usb_dev
, ICDI_READ_ENDPOINT
, (unsigned char *)h
->read_buffer
+ h
->read_count
,
196 h
->max_packet
- h
->read_count
, &transferred
, ICDI_READ_TIMEOUT
);
198 #ifdef _DEBUG_USB_COMMS_
199 LOG_DEBUG("received data: count %d", transferred
);
202 /* check for errors but retry for timeout */
205 if (result
== LIBUSB_ERROR_TIMEOUT
) {
206 LOG_DEBUG("Error RX timeout %d", result
);
208 LOG_DEBUG("Error RX Data %d", result
);
213 h
->read_count
+= transferred
;
215 /* we need to make sure we have a full packet, including checksum */
216 if (h
->read_count
> 5) {
218 /* check that we have received an packet delimiter
219 * we do not validate the checksum
220 * reply should contain $...#AA - so we check for # */
221 if (h
->read_buffer
[h
->read_count
- 3] == '#')
226 LOG_DEBUG("maximum data retries attempted");
234 static int icdi_send_cmd(void *handle
, const char *cmd
)
236 struct icdi_usb_handle_s
*h
;
237 h
= (struct icdi_usb_handle_s
*)handle
;
239 int cmd_len
= snprintf(h
->write_buffer
, h
->max_packet
, PACKET_START
"%s", cmd
);
240 return icdi_send_packet(handle
, cmd_len
);
243 static int icdi_send_remote_cmd(void *handle
, const char *data
)
245 struct icdi_usb_handle_s
*h
;
246 h
= (struct icdi_usb_handle_s
*)handle
;
248 size_t cmd_len
= sprintf(h
->write_buffer
, PACKET_START
"qRcmd,");
249 cmd_len
+= hexify(h
->write_buffer
+ cmd_len
, data
, 0, h
->max_packet
- cmd_len
);
251 return icdi_send_packet(handle
, cmd_len
);
254 static int icdi_get_cmd_result(void *handle
)
256 struct icdi_usb_handle_s
*h
;
260 assert(handle
!= NULL
);
261 h
= (struct icdi_usb_handle_s
*)handle
;
264 ch
= h
->read_buffer
[offset
++];
265 if (offset
> h
->read_count
)
269 if (memcmp("OK", h
->read_buffer
+ offset
, 2) == 0)
272 if (h
->read_buffer
[offset
] == 'E') {
275 if (unhexify(&result
, h
->read_buffer
+ offset
+ 1, 1) != 1)
280 /* for now we assume everything else is ok */
284 static int icdi_usb_idcode(void *handle
, uint32_t *idcode
)
289 static int icdi_usb_write_debug_reg(void *handle
, uint32_t addr
, uint32_t val
)
291 return icdi_usb_write_mem(handle
, addr
, 4, 1, (uint8_t *)&val
);
294 static enum target_state
icdi_usb_state(void *handle
)
297 struct icdi_usb_handle_s
*h
;
300 h
= (struct icdi_usb_handle_s
*)handle
;
302 result
= icdi_usb_read_mem(h
, DCB_DHCSR
, 4, 1, (uint8_t *)&dhcsr
);
303 if (result
!= ERROR_OK
)
304 return TARGET_UNKNOWN
;
307 return TARGET_HALTED
;
309 return TARGET_RUNNING
;
312 static int icdi_usb_version(void *handle
)
314 struct icdi_usb_handle_s
*h
;
315 h
= (struct icdi_usb_handle_s
*)handle
;
319 /* get info about icdi */
320 int result
= icdi_send_remote_cmd(handle
, "version");
321 if (result
!= ERROR_OK
)
324 if (h
->read_count
< 8) {
325 LOG_ERROR("Invalid Reply Received");
330 if (unhexify(version
, h
->read_buffer
+ 2, 4) != 4) {
331 LOG_WARNING("unable to get ICDI version");
335 /* null terminate and print info */
338 LOG_INFO("ICDI Firmware version: %s", version
);
343 static int icdi_usb_query(void *handle
)
347 struct icdi_usb_handle_s
*h
;
348 h
= (struct icdi_usb_handle_s
*)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
= strtoul(offset
+ 11, &separator
, 16);
371 LOG_ERROR("invalid max packet, using defaults");
373 h
->max_packet
= max_packet
;
374 LOG_DEBUG("max packet supported : %" PRIu32
" 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
, int num
, uint32_t *val
)
481 struct icdi_usb_handle_s
*h
;
484 h
= (struct icdi_usb_handle_s
*)handle
;
486 snprintf(cmd
, sizeof(cmd
), "p%x", num
);
487 result
= icdi_send_cmd(handle
, cmd
);
488 if (result
!= ERROR_OK
)
492 result
= icdi_get_cmd_result(handle
);
493 if (result
!= ERROR_OK
) {
494 LOG_ERROR("register read failed: 0x%x", result
);
499 if (unhexify((char *)val
, h
->read_buffer
+ 2, 4) != 4) {
500 LOG_ERROR("failed to convert result");
507 static int icdi_usb_write_reg(void *handle
, int num
, uint32_t val
)
512 int cmd_len
= snprintf(cmd
, sizeof(cmd
), "P%x=", num
);
513 hexify(cmd
+ cmd_len
, (char *)&val
, 4, sizeof(cmd
));
515 result
= icdi_send_cmd(handle
, cmd
);
516 if (result
!= ERROR_OK
)
520 result
= icdi_get_cmd_result(handle
);
521 if (result
!= ERROR_OK
) {
522 LOG_ERROR("register write failed: 0x%x", result
);
529 static int icdi_usb_read_mem_int(void *handle
, uint32_t addr
, uint32_t len
, uint8_t *buffer
)
532 struct icdi_usb_handle_s
*h
;
535 h
= (struct icdi_usb_handle_s
*)handle
;
537 snprintf(cmd
, sizeof(cmd
), "x%x,%x", 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%" PRIx32
" 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
;
564 h
= (struct icdi_usb_handle_s
*)handle
;
566 size_t cmd_len
= snprintf(h
->write_buffer
, h
->max_packet
, PACKET_START
"X%x,%x:", addr
, len
);
569 cmd_len
+= remote_escape_output((char *)buffer
, len
, h
->write_buffer
+ cmd_len
,
570 &out_len
, h
->max_packet
- cmd_len
);
572 if (out_len
< (int)len
) {
573 /* for now issue a error as we have no way of allocating a larger buffer */
574 LOG_ERROR("memory buffer too small: requires 0x%" PRIx32
" actual 0x%" PRIx32
, out_len
, len
);
578 result
= icdi_send_packet(handle
, cmd_len
);
579 if (result
!= ERROR_OK
)
583 result
= icdi_get_cmd_result(handle
);
584 if (result
!= ERROR_OK
) {
585 LOG_ERROR("memory write failed: 0x%x", result
);
592 static int icdi_usb_read_mem(void *handle
, uint32_t addr
, uint32_t size
,
593 uint32_t count
, uint8_t *buffer
)
597 return icdi_usb_read_mem_int(handle
, addr
, count
, buffer
);
600 static int icdi_usb_write_mem(void *handle
, uint32_t addr
, uint32_t size
,
601 uint32_t count
, const uint8_t *buffer
)
605 return icdi_usb_write_mem_int(handle
, addr
, count
, buffer
);
608 static int icdi_usb_close(void *handle
)
610 struct icdi_usb_handle_s
*h
;
612 h
= (struct icdi_usb_handle_s
*)handle
;
615 libusb_close(h
->usb_dev
);
618 libusb_exit(h
->usb_ctx
);
621 free(h
->read_buffer
);
624 free(h
->write_buffer
);
631 static int icdi_usb_open(struct hl_interface_param_s
*param
, void **fd
)
634 struct icdi_usb_handle_s
*h
;
636 LOG_DEBUG("icdi_usb_open");
638 h
= calloc(1, sizeof(struct icdi_usb_handle_s
));
641 LOG_ERROR("unable to allocate memory");
645 LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param
->transport
,
646 param
->vid
, param
->pid
);
648 if (libusb_init(&h
->usb_ctx
) != 0) {
649 LOG_ERROR("libusb init failed");
653 h
->usb_dev
= libusb_open_device_with_vid_pid(h
->usb_ctx
, param
->vid
, param
->pid
);
655 LOG_ERROR("open failed");
659 if (libusb_claim_interface(h
->usb_dev
, 2)) {
660 LOG_DEBUG("claim interface failed");
664 /* check if mode is supported */
667 switch (param
->transport
) {
669 /* TODO place holder as swd is not currently supported */
670 case HL_TRANSPORT_SWD
:
672 case HL_TRANSPORT_JTAG
:
679 if (retval
!= ERROR_OK
) {
680 LOG_ERROR("mode (transport) not supported by device");
684 /* allocate buffer */
685 h
->read_buffer
= malloc(ICDI_PACKET_SIZE
);
686 h
->write_buffer
= malloc(ICDI_PACKET_SIZE
);
687 h
->max_packet
= ICDI_PACKET_SIZE
;
689 if (h
->read_buffer
== 0 || h
->write_buffer
== 0) {
690 LOG_DEBUG("malloc failed");
694 /* query icdi version etc */
695 retval
= icdi_usb_version(h
);
696 if (retval
!= ERROR_OK
)
699 /* query icdi support */
700 retval
= icdi_usb_query(h
);
701 if (retval
!= ERROR_OK
)
706 /* set the max target read/write buffer in bytes
707 * as we are using gdb binary packets to transfer memory we have to
708 * reserve half the buffer for any possible escape chars plus
709 * at least 64 bytes for the gdb packet header */
710 param
->max_buffer
= (((h
->max_packet
- 64) / 4) * 4) / 2;
720 struct hl_layout_api_s icdi_usb_layout_api
= {
721 .open
= icdi_usb_open
,
722 .close
= icdi_usb_close
,
723 .idcode
= icdi_usb_idcode
,
724 .state
= icdi_usb_state
,
725 .reset
= icdi_usb_reset
,
726 .assert_srst
= icdi_usb_assert_srst
,
728 .halt
= icdi_usb_halt
,
729 .step
= icdi_usb_step
,
730 .read_regs
= icdi_usb_read_regs
,
731 .read_reg
= icdi_usb_read_reg
,
732 .write_reg
= icdi_usb_write_reg
,
733 .read_mem
= icdi_usb_read_mem
,
734 .write_mem
= icdi_usb_write_mem
,
735 .write_debug_reg
= icdi_usb_write_debug_reg