]> git.sur5r.net Git - openocd/blob - src/jtag/drivers/ti_icdi_usb.c
ti_icdi: add icdi_usb_query result check
[openocd] / src / jtag / drivers / ti_icdi_usb.c
1 /***************************************************************************
2  *                                                                         *
3  *   Copyright (C) 2012 by Spencer Oliver                                  *
4  *   spen@spen-soft.co.uk                                                  *
5  *                                                                         *
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.                                   *
10  *                                                                         *
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.                          *
15  *                                                                         *
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  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20  ***************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
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>
33
34 #include <target/cortex_m.h>
35
36 #include <libusb-1.0/libusb.h>
37
38 #define ICDI_WRITE_ENDPOINT 0x02
39 #define ICDI_READ_ENDPOINT 0x83
40
41 #define ICDI_WRITE_TIMEOUT 1000
42 #define ICDI_READ_TIMEOUT 1000
43 #define ICDI_PACKET_SIZE 2048
44
45 #define PACKET_START "$"
46 #define PACKET_END "#"
47
48 struct icdi_usb_handle_s {
49         libusb_context *usb_ctx;
50         libusb_device_handle *usb_dev;
51
52         char *read_buffer;
53         char *write_buffer;
54         int max_packet;
55         int read_count;
56 };
57
58 static int icdi_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, uint8_t *buffer);
59 static int icdi_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, const uint8_t *buffer);
60
61 static int remote_escape_output(const char *buffer, int len, char *out_buf, int *out_len, int out_maxlen)
62 {
63         int input_index, output_index;
64
65         output_index = 0;
66
67         for (input_index = 0; input_index < len; input_index++) {
68
69                 char b = buffer[input_index];
70
71                 if (b == '$' || b == '#' || b == '}' || b == '*') {
72                         /* These must be escaped.  */
73                         if (output_index + 2 > out_maxlen)
74                                 break;
75                         out_buf[output_index++] = '}';
76                         out_buf[output_index++] = b ^ 0x20;
77                 } else {
78                         if (output_index + 1 > out_maxlen)
79                                 break;
80                         out_buf[output_index++] = b;
81                 }
82         }
83
84         *out_len = input_index;
85         return output_index;
86 }
87
88 static int remote_unescape_input(const char *buffer, int len, char *out_buf, int out_maxlen)
89 {
90         int input_index, output_index;
91         int escaped;
92
93         output_index = 0;
94         escaped = 0;
95
96         for (input_index = 0; input_index < len; input_index++) {
97
98                 char b = buffer[input_index];
99
100                 if (output_index + 1 > out_maxlen)
101                         LOG_ERROR("Received too much data from the target.");
102
103                 if (escaped) {
104                         out_buf[output_index++] = b ^ 0x20;
105                         escaped = 0;
106                 } else if (b == '}')
107                         escaped = 1;
108                 else
109                         out_buf[output_index++] = b;
110         }
111
112         if (escaped)
113                 LOG_ERROR("Unmatched escape character in target response.");
114
115         return output_index;
116 }
117
118 static int icdi_send_packet(void *handle, int len)
119 {
120         unsigned char cksum = 0;
121         struct icdi_usb_handle_s *h;
122         int result, retry = 0;
123         int transferred = 0;
124
125         assert(handle != NULL);
126         h = (struct icdi_usb_handle_s *)handle;
127
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");
131                 return ERROR_FAIL;
132         }
133
134         /* calculate checksum - offset start of packet */
135         for (int i = 1; i < len; i++)
136                 cksum += h->write_buffer[i];
137
138         len += sprintf(&h->write_buffer[len], PACKET_END "%02x", cksum);
139
140 #ifdef _DEBUG_USB_COMMS_
141         char buffer[50];
142         char ch = h->write_buffer[1];
143         if (ch == 'x' || ch == 'X')
144                 LOG_DEBUG("writing packet: <binary>");
145         else {
146                 memcpy(buffer, h->write_buffer, len >= 50 ? 50-1 : len);
147                 buffer[len] = 0;
148                 LOG_DEBUG("writing packet: %s", buffer);
149         }
150 #endif
151
152         while (1) {
153
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);
158                         return ERROR_FAIL;
159                 }
160
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);
166                         return ERROR_FAIL;
167                 }
168
169 #ifdef _DEBUG_USB_COMMS_
170                 LOG_DEBUG("received reply: '%c' : count %d", h->read_buffer[0], transferred);
171 #endif
172
173                 if (h->read_buffer[0] == '-') {
174                         LOG_DEBUG("Resending packet %d", ++retry);
175                 } else {
176                         if (h->read_buffer[0] != '+')
177                                 LOG_DEBUG("Unexpected Reply from ICDI: %c", h->read_buffer[0]);
178                         break;
179                 }
180
181                 if (retry == 3) {
182                         LOG_DEBUG("maximum nack retries attempted");
183                         return ERROR_FAIL;
184                 }
185         }
186
187         retry = 0;
188         h->read_count = transferred;
189
190         while (1) {
191
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);
195
196 #ifdef _DEBUG_USB_COMMS_
197                 LOG_DEBUG("received data: count %d", transferred);
198 #endif
199
200                 /* check for errors but retry for timeout */
201                 if (result != 0) {
202
203                         if (result == LIBUSB_ERROR_TIMEOUT) {
204                                 LOG_DEBUG("Error RX timeout %d", result);
205                         } else {
206                                 LOG_DEBUG("Error RX Data %d", result);
207                                 return ERROR_FAIL;
208                         }
209                 }
210
211                 h->read_count += transferred;
212
213                 /* we need to make sure we have a full packet, including checksum */
214                 if (h->read_count > 5) {
215
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] == '#')
220                                 return ERROR_OK;
221                 }
222
223                 if (retry++ == 3) {
224                         LOG_DEBUG("maximum data retries attempted");
225                         break;
226                 }
227         }
228
229         return ERROR_FAIL;
230 }
231
232 static int icdi_send_cmd(void *handle, const char *cmd)
233 {
234         struct icdi_usb_handle_s *h;
235         h = (struct icdi_usb_handle_s *)handle;
236
237         int cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "%s", cmd);
238         return icdi_send_packet(handle, cmd_len);
239 }
240
241 static int icdi_send_remote_cmd(void *handle, const char *data)
242 {
243         struct icdi_usb_handle_s *h;
244         h = (struct icdi_usb_handle_s *)handle;
245
246         size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,");
247         cmd_len += hexify(h->write_buffer + cmd_len, data, 0, h->max_packet - cmd_len);
248
249         return icdi_send_packet(handle, cmd_len);
250 }
251
252 static int icdi_get_cmd_result(void *handle)
253 {
254         struct icdi_usb_handle_s *h;
255         int offset = 0;
256         char ch;
257
258         assert(handle != NULL);
259         h = (struct icdi_usb_handle_s *)handle;
260
261         do {
262                 ch = h->read_buffer[offset++];
263                 if (offset > h->read_count)
264                         return ERROR_FAIL;
265         } while (ch != '$');
266
267         if (memcmp("OK", h->read_buffer + offset, 2) == 0)
268                 return ERROR_OK;
269
270         if (h->read_buffer[offset] == 'E') {
271                 /* get error code */
272                 char result;
273                 if (unhexify(&result, h->read_buffer + offset + 1, 1) != 1)
274                         return ERROR_FAIL;
275                 return result;
276         }
277
278         /* for now we assume everything else is ok */
279         return ERROR_OK;
280 }
281
282 static int icdi_usb_idcode(void *handle, uint32_t *idcode)
283 {
284         return ERROR_OK;
285 }
286
287 static int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)
288 {
289         return icdi_usb_write_mem32(handle, addr, 1, (uint8_t *)&val);
290 }
291
292 static enum target_state icdi_usb_state(void *handle)
293 {
294         int result;
295         struct icdi_usb_handle_s *h;
296         uint32_t dhcsr;
297
298         h = (struct icdi_usb_handle_s *)handle;
299
300         result = icdi_usb_read_mem32(h, DCB_DHCSR, 1, (uint8_t *)&dhcsr);
301         if (result != ERROR_OK)
302                 return TARGET_UNKNOWN;
303
304         if (dhcsr & S_HALT)
305                 return TARGET_HALTED;
306
307         return TARGET_RUNNING;
308 }
309
310 static int icdi_usb_version(void *handle)
311 {
312         struct icdi_usb_handle_s *h;
313         h = (struct icdi_usb_handle_s *)handle;
314
315         char version[20];
316
317         /* get info about icdi */
318         int result = icdi_send_remote_cmd(handle, "version");
319         if (result != ERROR_OK)
320                 return result;
321
322         if (h->read_count < 8) {
323                 LOG_ERROR("Invalid Reply Received");
324                 return ERROR_FAIL;
325         }
326
327         /* convert reply */
328         if (unhexify(version, h->read_buffer + 2, 4) != 4) {
329                 LOG_WARNING("unable to get ICDI version");
330                 return ERROR_OK;
331         }
332
333         /* null terminate and print info */
334         version[4] = 0;
335
336         LOG_INFO("ICDI Firmware version: %s", version);
337
338         return ERROR_OK;
339 }
340
341 static int icdi_usb_query(void *handle)
342 {
343         int result;
344
345         struct icdi_usb_handle_s *h;
346         h = (struct icdi_usb_handle_s *)handle;
347
348         result = icdi_send_cmd(handle, "qSupported");
349         if (result != ERROR_OK)
350                 return result;
351
352         /* check result */
353         result = icdi_get_cmd_result(handle);
354         if (result != ERROR_OK) {
355                 LOG_ERROR("query supported failed: 0x%x", result);
356                 return ERROR_FAIL;
357         }
358
359         /* from this we can get the max packet supported */
360
361         /* query packet buffer size */
362         char *offset = strstr(h->read_buffer, "PacketSize");
363         if (offset) {
364                 char *separator;
365                 int max_packet;
366
367                 max_packet = strtoul(offset + 11, &separator, 16);
368                 if (!max_packet)
369                         LOG_ERROR("invalid max packet, using defaults");
370                 else
371                         h->max_packet = max_packet;
372                 LOG_DEBUG("max packet supported : %" PRIu32 " bytes", h->max_packet);
373         }
374
375
376         /* if required re allocate packet buffer */
377         if (h->max_packet != ICDI_PACKET_SIZE) {
378                 h->read_buffer = realloc(h->read_buffer, h->max_packet);
379                 h->write_buffer = realloc(h->write_buffer, h->max_packet);
380                 if (h->read_buffer == 0 || h->write_buffer == 0) {
381                         LOG_ERROR("unable to reallocate memory");
382                         return ERROR_FAIL;
383                 }
384         }
385
386         /* set extended mode */
387         result = icdi_send_cmd(handle, "!");
388         if (result != ERROR_OK)
389                 return result;
390
391         /* check result */
392         result = icdi_get_cmd_result(handle);
393         if (result != ERROR_OK) {
394                 LOG_ERROR("unable to enable extended mode: 0x%x", result);
395                 return ERROR_FAIL;
396         }
397
398         return ERROR_OK;
399 }
400
401 static int icdi_usb_reset(void *handle)
402 {
403         /* we do this in hla_target.c */
404         return ERROR_OK;
405 }
406
407 static int icdi_usb_assert_srst(void *handle, int srst)
408 {
409         /* TODO not supported yet */
410         return ERROR_COMMAND_NOTFOUND;
411 }
412
413 static int icdi_usb_run(void *handle)
414 {
415         int result;
416
417         /* resume target at current address */
418         result = icdi_send_cmd(handle, "c");
419         if (result != ERROR_OK)
420                 return result;
421
422         /* check result */
423         result = icdi_get_cmd_result(handle);
424         if (result != ERROR_OK) {
425                 LOG_ERROR("continue failed: 0x%x", result);
426                 return ERROR_FAIL;
427         }
428
429         return result;
430 }
431
432 static int icdi_usb_halt(void *handle)
433 {
434         int result;
435
436         /* this query halts the target ?? */
437         result = icdi_send_cmd(handle, "?");
438         if (result != ERROR_OK)
439                 return result;
440
441         /* check result */
442         result = icdi_get_cmd_result(handle);
443         if (result != ERROR_OK) {
444                 LOG_ERROR("halt failed: 0x%x", result);
445                 return ERROR_FAIL;
446         }
447
448         return result;
449 }
450
451 static int icdi_usb_step(void *handle)
452 {
453         int result;
454
455         /* step target at current address */
456         result = icdi_send_cmd(handle, "s");
457         if (result != ERROR_OK)
458                 return result;
459
460         /* check result */
461         result = icdi_get_cmd_result(handle);
462         if (result != ERROR_OK) {
463                 LOG_ERROR("step failed: 0x%x", result);
464                 return ERROR_FAIL;
465         }
466
467         return result;
468 }
469
470 static int icdi_usb_read_regs(void *handle)
471 {
472         /* currently unsupported */
473         return ERROR_OK;
474 }
475
476 static int icdi_usb_read_reg(void *handle, int num, uint32_t *val)
477 {
478         int result;
479         struct icdi_usb_handle_s *h;
480         char cmd[10];
481
482         h = (struct icdi_usb_handle_s *)handle;
483
484         snprintf(cmd, sizeof(cmd), "p%x", num);
485         result = icdi_send_cmd(handle, cmd);
486         if (result != ERROR_OK)
487                 return result;
488
489         /* check result */
490         result = icdi_get_cmd_result(handle);
491         if (result != ERROR_OK) {
492                 LOG_ERROR("register read failed: 0x%x", result);
493                 return ERROR_FAIL;
494         }
495
496         /* convert result */
497         if (unhexify((char *)val, h->read_buffer + 2, 4) != 4) {
498                 LOG_ERROR("failed to convert result");
499                 return ERROR_FAIL;
500         }
501
502         return result;
503 }
504
505 static int icdi_usb_write_reg(void *handle, int num, uint32_t val)
506 {
507         int result;
508         char cmd[20];
509
510         int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", num);
511         hexify(cmd + cmd_len, (char *)&val, 4, sizeof(cmd));
512
513         result = icdi_send_cmd(handle, cmd);
514         if (result != ERROR_OK)
515                 return result;
516
517         /* check result */
518         result = icdi_get_cmd_result(handle);
519         if (result != ERROR_OK) {
520                 LOG_ERROR("register write failed: 0x%x", result);
521                 return ERROR_FAIL;
522         }
523
524         return result;
525 }
526
527 static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t len, uint8_t *buffer)
528 {
529         int result;
530         struct icdi_usb_handle_s *h;
531         char cmd[20];
532
533         h = (struct icdi_usb_handle_s *)handle;
534
535         snprintf(cmd, sizeof(cmd), "x%x,%x", addr, len);
536         result = icdi_send_cmd(handle, cmd);
537         if (result != ERROR_OK)
538                 return result;
539
540         /* check result */
541         result = icdi_get_cmd_result(handle);
542         if (result != ERROR_OK) {
543                 LOG_ERROR("memory read failed: 0x%x", result);
544                 return ERROR_FAIL;
545         }
546
547         /* unescape input */
548         int read_len = remote_unescape_input(h->read_buffer + 5, h->read_count - 8, (char *)buffer, len);
549         if (read_len != (int)len) {
550                 LOG_ERROR("read more bytes than expected: actual 0x%" PRIx32 " expected 0x%" PRIx32, read_len, len);
551                 return ERROR_FAIL;
552         }
553
554         return ERROR_OK;
555 }
556
557 static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t len, const uint8_t *buffer)
558 {
559         int result;
560         struct icdi_usb_handle_s *h;
561
562         h = (struct icdi_usb_handle_s *)handle;
563
564         size_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "X%x,%x:", addr, len);
565
566         int out_len;
567         cmd_len += remote_escape_output((char *)buffer, len, h->write_buffer + cmd_len,
568                         &out_len, h->max_packet - cmd_len);
569
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%" PRIx32 " actual 0x%" PRIx32, out_len, len);
573                 return ERROR_FAIL;
574         }
575
576         result = icdi_send_packet(handle, cmd_len);
577         if (result != ERROR_OK)
578                 return result;
579
580         /* check result */
581         result = icdi_get_cmd_result(handle);
582         if (result != ERROR_OK) {
583                 LOG_ERROR("memory write failed: 0x%x", result);
584                 return ERROR_FAIL;
585         }
586
587         return ERROR_OK;
588 }
589
590 static int icdi_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, uint8_t *buffer)
591 {
592         return icdi_usb_read_mem(handle, addr, len, buffer);
593 }
594
595 static int icdi_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, const uint8_t *buffer)
596 {
597         return icdi_usb_write_mem(handle, addr, len, buffer);
598 }
599
600 static int icdi_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, uint8_t *buffer)
601 {
602         return icdi_usb_read_mem(handle, addr, len * 4, buffer);
603 }
604
605 static int icdi_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, const uint8_t *buffer)
606 {
607         return icdi_usb_write_mem(handle, addr, len * 4, buffer);
608 }
609
610 static int icdi_usb_close(void *handle)
611 {
612         struct icdi_usb_handle_s *h;
613
614         h = (struct icdi_usb_handle_s *)handle;
615
616         if (h->usb_dev)
617                 libusb_close(h->usb_dev);
618
619         if (h->usb_ctx)
620                 libusb_exit(h->usb_ctx);
621
622         if (h->read_buffer)
623                 free(h->read_buffer);
624
625         if (h->write_buffer)
626                 free(h->write_buffer);
627
628         free(handle);
629
630         return ERROR_OK;
631 }
632
633 static int icdi_usb_open(struct hl_interface_param_s *param, void **fd)
634 {
635         int retval;
636         struct icdi_usb_handle_s *h;
637
638         LOG_DEBUG("icdi_usb_open");
639
640         h = calloc(1, sizeof(struct icdi_usb_handle_s));
641
642         if (h == 0) {
643                 LOG_ERROR("unable to allocate memory");
644                 return ERROR_FAIL;
645         }
646
647         LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param->transport,
648                 param->vid, param->pid);
649
650         if (libusb_init(&h->usb_ctx) != 0) {
651                 LOG_ERROR("libusb init failed");
652                 goto error_open;
653         }
654
655         h->usb_dev = libusb_open_device_with_vid_pid(h->usb_ctx, param->vid, param->pid);
656         if (!h->usb_dev) {
657                 LOG_ERROR("open failed");
658                 goto error_open;
659         }
660
661         if (libusb_claim_interface(h->usb_dev, 2)) {
662                 LOG_DEBUG("claim interface failed");
663                 goto error_open;
664         }
665
666         /* check if mode is supported */
667         retval = ERROR_OK;
668
669         switch (param->transport) {
670 #if 0
671                 /* TODO place holder as swd is not currently supported */
672                 case HL_TRANSPORT_SWD:
673 #endif
674                 case HL_TRANSPORT_JTAG:
675                         break;
676                 default:
677                         retval = ERROR_FAIL;
678                         break;
679         }
680
681         if (retval != ERROR_OK) {
682                 LOG_ERROR("mode (transport) not supported by device");
683                 goto error_open;
684         }
685
686         /* allocate buffer */
687         h->read_buffer = malloc(ICDI_PACKET_SIZE);
688         h->write_buffer = malloc(ICDI_PACKET_SIZE);
689         h->max_packet = ICDI_PACKET_SIZE;
690
691         if (h->read_buffer == 0 || h->write_buffer == 0) {
692                 LOG_DEBUG("malloc failed");
693                 goto error_open;
694         }
695
696         /* query icdi version etc */
697         retval = icdi_usb_version(h);
698         if (retval != ERROR_OK)
699                 goto error_open;
700
701         /* query icdi support */
702         retval = icdi_usb_query(h);
703         if (retval != ERROR_OK)
704                 goto error_open;
705
706         *fd = h;
707
708         /* set the max target read/write buffer in bytes
709          * as we are using gdb binary packets to transfer memory we have to
710          * reserve half the buffer for any possible escape chars plus
711          * at least 64 bytes for the gdb packet header */
712         param->max_buffer = (((h->max_packet - 64) / 4) * 4) / 2;
713
714         return ERROR_OK;
715
716 error_open:
717         icdi_usb_close(h);
718
719         return ERROR_FAIL;
720 }
721
722 struct hl_layout_api_s icdi_usb_layout_api = {
723         .open = icdi_usb_open,
724         .close = icdi_usb_close,
725         .idcode = icdi_usb_idcode,
726         .state = icdi_usb_state,
727         .reset = icdi_usb_reset,
728         .assert_srst = icdi_usb_assert_srst,
729         .run = icdi_usb_run,
730         .halt = icdi_usb_halt,
731         .step = icdi_usb_step,
732         .read_regs = icdi_usb_read_regs,
733         .read_reg = icdi_usb_read_reg,
734         .write_reg = icdi_usb_write_reg,
735         .read_mem8 = icdi_usb_read_mem8,
736         .write_mem8 = icdi_usb_write_mem8,
737         .read_mem32 = icdi_usb_read_mem32,
738         .write_mem32 = icdi_usb_write_mem32,
739         .write_debug_reg = icdi_usb_write_debug_reg
740 };