jtag: opendous: fix tap buffer overflow
[openocd.git] / src / jtag / drivers / opendous.c
1 /***************************************************************************
2 * *
3 * Copyright (C) 2009 by Cahya Wirawan <cahya@gmx.at> *
4 * Based on opendous driver by Vladimir Fonov *
5 * *
6 * Copyright (C) 2009 by Vladimir Fonov <vladimir.fonov@gmai.com> *
7 * Based on J-link driver by Juergen Stuber *
8 * *
9 * Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net> *
10 * based on Dominic Rath's and Benedikt Sauter's usbprog.c *
11 * *
12 * Copyright (C) 2008 by Spencer Oliver *
13 * spen@spen-soft.co.uk *
14 * *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
19 * *
20 * This program is distributed in the hope that it will be useful, *
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
23 * GNU General Public License for more details. *
24 * *
25 * You should have received a copy of the GNU General Public License *
26 * along with this program; if not, write to the *
27 * Free Software Foundation, Inc., *
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 ***************************************************************************/
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <jtag/interface.h>
36 #include <jtag/commands.h>
37 #include "libusb_common.h"
38 #include <string.h>
39 #include <sys/timeb.h>
40 #include <time.h>
41
42 #define ESTICK_VID 0x1781
43 #define ESTICK_PID 0xC0C0
44
45 #define OPENDOUS_VID 0x03EB
46 #define OPENDOUS_PID 0x204F
47
48 /* pid could be specified at runtime */
49 static uint16_t vids[] = { OPENDOUS_VID, ESTICK_VID, 0 };
50 static uint16_t pids[] = { OPENDOUS_PID, ESTICK_PID, 0 };
51
52 #define OPENDOUS_WRITE_ENDPOINT 0x02
53 #define OPENDOUS_READ_ENDPOINT 0x81
54
55 static unsigned int opendous_hw_jtag_version = 1;
56
57 #define OPENDOUS_USB_TIMEOUT 1000
58
59 #define OPENDOUS_USB_BUFFER_SIZE 360
60 #define OPENDOUS_IN_BUFFER_SIZE (OPENDOUS_USB_BUFFER_SIZE)
61 #define OPENDOUS_OUT_BUFFER_SIZE (OPENDOUS_USB_BUFFER_SIZE)
62
63 /* Global USB buffers */
64 static uint8_t usb_in_buffer[OPENDOUS_IN_BUFFER_SIZE];
65 static uint8_t usb_out_buffer[OPENDOUS_OUT_BUFFER_SIZE];
66
67 /* Constants for OPENDOUS command */
68
69 #define OPENDOUS_MAX_SPEED 66
70 #define OPENDOUS_MAX_TAP_TRANSMIT 350 /* even number is easier to handle */
71 #define OPENDOUS_MAX_INPUT_DATA (OPENDOUS_MAX_TAP_TRANSMIT*4)
72
73 #define OPENDOUS_TAP_BUFFER_SIZE 65536
74
75 #define MAX_PENDING_SCAN_RESULTS (OPENDOUS_MAX_INPUT_DATA)
76
77 /* JTAG usb commands */
78 #define JTAG_CMD_TAP_OUTPUT 0x0
79 #define JTAG_CMD_SET_TRST 0x1
80 #define JTAG_CMD_SET_SRST 0x2
81 #define JTAG_CMD_READ_INPUT 0x3
82 #define JTAG_CMD_TAP_OUTPUT_EMU 0x4
83 #define JTAG_CMD_SET_DELAY 0x5
84 #define JTAG_CMD_SET_SRST_TRST 0x6
85 #define JTAG_CMD_READ_CONFIG 0x7
86
87 /* External interface functions */
88 static int opendous_execute_queue(void);
89 static int opendous_init(void);
90 static int opendous_quit(void);
91
92 /* Queue command functions */
93 static void opendous_end_state(tap_state_t state);
94 static void opendous_state_move(void);
95 static void opendous_path_move(int num_states, tap_state_t *path);
96 static void opendous_runtest(int num_cycles);
97 static void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer,
98 int scan_size, struct scan_command *command);
99 static void opendous_reset(int trst, int srst);
100 static void opendous_simple_command(uint8_t command, uint8_t _data);
101 static int opendous_get_status(void);
102
103 /* opendous tap buffer functions */
104 static void opendous_tap_init(void);
105 static int opendous_tap_execute(void);
106 static void opendous_tap_ensure_space(int scans, int bits);
107 static void opendous_tap_append_step(int tms, int tdi);
108 static void opendous_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command);
109
110 /* opendous lowlevel functions */
111 struct opendous_jtag {
112 struct jtag_libusb_device_handle *usb_handle;
113 };
114
115 static struct opendous_jtag *opendous_usb_open(void);
116 static void opendous_usb_close(struct opendous_jtag *opendous_jtag);
117 static int opendous_usb_message(struct opendous_jtag *opendous_jtag, int out_length, int in_length);
118 static int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length);
119 static int opendous_usb_read(struct opendous_jtag *opendous_jtag);
120
121 /* helper functions */
122 int opendous_get_version_info(void);
123
124 #ifdef _DEBUG_USB_COMMS_
125 char time_str[50];
126 static void opendous_debug_buffer(uint8_t *buffer, int length);
127 char *opendous_get_time(char *);
128 #endif
129
130 static struct opendous_jtag *opendous_jtag_handle;
131
132 /***************************************************************************/
133 /* External interface implementation */
134
135 COMMAND_HANDLER(opendous_handle_opendous_info_command)
136 {
137 if (opendous_get_version_info() == ERROR_OK) {
138 /* attempt to get status */
139 opendous_get_status();
140 }
141
142 return ERROR_OK;
143 }
144
145 COMMAND_HANDLER(opendous_handle_opendous_hw_jtag_command)
146 {
147 switch (CMD_ARGC) {
148 case 0:
149 command_print(CMD_CTX, "opendous hw jtag %i", opendous_hw_jtag_version);
150 break;
151
152 case 1: {
153 int request_version = atoi(CMD_ARGV[0]);
154 switch (request_version) {
155 case 2:
156 case 3:
157 opendous_hw_jtag_version = request_version;
158 break;
159
160 default:
161 return ERROR_COMMAND_SYNTAX_ERROR;
162 }
163 break;
164 }
165
166 default:
167 return ERROR_COMMAND_SYNTAX_ERROR;
168 }
169
170 return ERROR_OK;
171 }
172
173 static const struct command_registration opendous_command_handlers[] = {
174 {
175 .name = "opendous_info",
176 .handler = &opendous_handle_opendous_info_command,
177 .mode = COMMAND_EXEC,
178 .help = "show opendous info",
179 },
180 {
181 .name = "opendous_hw_jtag",
182 .handler = &opendous_handle_opendous_hw_jtag_command,
183 .mode = COMMAND_EXEC,
184 .help = "access opendous HW JTAG command version",
185 .usage = "[2|3]",
186 },
187 COMMAND_REGISTRATION_DONE
188 };
189
190 struct jtag_interface opendous_interface = {
191 .name = "opendous",
192 .commands = opendous_command_handlers,
193 .execute_queue = opendous_execute_queue,
194 .init = opendous_init,
195 .quit = opendous_quit,
196 };
197
198 static int opendous_execute_queue(void)
199 {
200 struct jtag_command *cmd = jtag_command_queue;
201 int scan_size;
202 enum scan_type type;
203 uint8_t *buffer;
204
205 while (cmd != NULL) {
206 switch (cmd->type) {
207 case JTAG_RUNTEST:
208 DEBUG_JTAG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, \
209 cmd->cmd.runtest->end_state);
210
211 if (cmd->cmd.runtest->end_state != -1)
212 opendous_end_state(cmd->cmd.runtest->end_state);
213 opendous_runtest(cmd->cmd.runtest->num_cycles);
214 break;
215
216 case JTAG_TLR_RESET:
217 DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
218
219 if (cmd->cmd.statemove->end_state != -1)
220 opendous_end_state(cmd->cmd.statemove->end_state);
221 opendous_state_move();
222 break;
223
224 case JTAG_PATHMOVE:
225 DEBUG_JTAG_IO("pathmove: %i states, end in %i", \
226 cmd->cmd.pathmove->num_states, \
227 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
228
229 opendous_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
230 break;
231
232 case JTAG_SCAN:
233 DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state);
234
235 if (cmd->cmd.scan->end_state != -1)
236 opendous_end_state(cmd->cmd.scan->end_state);
237
238 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
239 DEBUG_JTAG_IO("scan input, length = %d", scan_size);
240
241 #ifdef _DEBUG_USB_COMMS_
242 opendous_debug_buffer(buffer, (scan_size + 7) / 8);
243 #endif
244 type = jtag_scan_type(cmd->cmd.scan);
245 opendous_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan);
246 break;
247
248 case JTAG_RESET:
249 DEBUG_JTAG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
250
251 opendous_tap_execute();
252
253 if (cmd->cmd.reset->trst == 1)
254 tap_set_state(TAP_RESET);
255 opendous_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
256 break;
257
258 case JTAG_SLEEP:
259 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
260 opendous_tap_execute();
261 jtag_sleep(cmd->cmd.sleep->us);
262 break;
263
264 default:
265 LOG_ERROR("BUG: unknown JTAG command type encountered");
266 exit(-1);
267 }
268 cmd = cmd->next;
269 }
270 return opendous_tap_execute();
271 }
272
273 static int opendous_init(void)
274 {
275 int check_cnt;
276
277 opendous_jtag_handle = opendous_usb_open();
278
279 if (opendous_jtag_handle == 0) {
280 LOG_ERROR("Cannot find opendous Interface! Please check connection and permissions.");
281 return ERROR_JTAG_INIT_FAILED;
282 }
283
284 check_cnt = 0;
285 while (check_cnt < 3) {
286 if (opendous_get_version_info() == ERROR_OK) {
287 /* attempt to get status */
288 opendous_get_status();
289 break;
290 }
291
292 check_cnt++;
293 }
294
295 LOG_INFO("opendous JTAG Interface ready");
296
297 opendous_reset(0, 0);
298 opendous_tap_init();
299
300 return ERROR_OK;
301 }
302
303 static int opendous_quit(void)
304 {
305 opendous_usb_close(opendous_jtag_handle);
306 return ERROR_OK;
307 }
308
309 /***************************************************************************/
310 /* Queue command implementations */
311
312 void opendous_end_state(tap_state_t state)
313 {
314 if (tap_is_state_stable(state))
315 tap_set_end_state(state);
316 else {
317 LOG_ERROR("BUG: %i is not a valid end state", state);
318 exit(-1);
319 }
320 }
321
322 /* Goes to the end state. */
323 void opendous_state_move(void)
324 {
325 int i;
326 int tms = 0;
327 uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
328 uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
329
330 for (i = 0; i < tms_scan_bits; i++) {
331 tms = (tms_scan >> i) & 1;
332 opendous_tap_append_step(tms, 0);
333 }
334
335 tap_set_state(tap_get_end_state());
336 }
337
338 void opendous_path_move(int num_states, tap_state_t *path)
339 {
340 int i;
341
342 for (i = 0; i < num_states; i++) {
343 if (path[i] == tap_state_transition(tap_get_state(), false))
344 opendous_tap_append_step(0, 0);
345 else if (path[i] == tap_state_transition(tap_get_state(), true))
346 opendous_tap_append_step(1, 0);
347 else {
348 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
349 tap_state_name(tap_get_state()), tap_state_name(path[i]));
350 exit(-1);
351 }
352
353 tap_set_state(path[i]);
354 }
355
356 tap_set_end_state(tap_get_state());
357 }
358
359 void opendous_runtest(int num_cycles)
360 {
361 int i;
362
363 tap_state_t saved_end_state = tap_get_end_state();
364
365 /* only do a state_move when we're not already in IDLE */
366 if (tap_get_state() != TAP_IDLE) {
367 opendous_end_state(TAP_IDLE);
368 opendous_state_move();
369 }
370
371 /* execute num_cycles */
372 for (i = 0; i < num_cycles; i++)
373 opendous_tap_append_step(0, 0);
374
375 /* finish in end_state */
376 opendous_end_state(saved_end_state);
377 if (tap_get_state() != tap_get_end_state())
378 opendous_state_move();
379 }
380
381 void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command)
382 {
383 tap_state_t saved_end_state;
384
385 opendous_tap_ensure_space(1, scan_size + 8);
386
387 saved_end_state = tap_get_end_state();
388
389 /* Move to appropriate scan state */
390 opendous_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
391
392 if (tap_get_state() != tap_get_end_state())
393 opendous_state_move();
394
395 opendous_end_state(saved_end_state);
396
397 /* Scan */
398 opendous_tap_append_scan(scan_size, buffer, command);
399
400 /* We are in Exit1, go to Pause */
401 opendous_tap_append_step(0, 0);
402
403 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
404
405 if (tap_get_state() != tap_get_end_state())
406 opendous_state_move();
407 }
408
409 void opendous_reset(int trst, int srst)
410 {
411 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
412
413 /* Signals are active low */
414 #if 0
415 if (srst == 0)
416 opendous_simple_command(JTAG_CMD_SET_SRST, 1);
417 else if (srst == 1)
418 opendous_simple_command(JTAG_CMD_SET_SRST, 0);
419
420 if (trst == 0)
421 opendous_simple_command(JTAG_CMD_SET_TRST, 1);
422 else if (trst == 1)
423 opendous_simple_command(JTAG_CMD_SET_TRST, 0);
424 #endif
425
426 srst = srst ? 0 : 1;
427 trst = trst ? 0 : 2;
428 opendous_simple_command(JTAG_CMD_SET_SRST_TRST, srst | trst);
429 }
430
431 void opendous_simple_command(uint8_t command, uint8_t _data)
432 {
433 int result;
434
435 DEBUG_JTAG_IO("0x%02x 0x%02x", command, _data);
436
437 usb_out_buffer[0] = 2;
438 usb_out_buffer[1] = 0;
439 usb_out_buffer[2] = command;
440 usb_out_buffer[3] = _data;
441
442 result = opendous_usb_message(opendous_jtag_handle, 4, 1);
443 if (result != 1)
444 LOG_ERROR("opendous command 0x%02x failed (%d)", command, result);
445 }
446
447 int opendous_get_status(void)
448 {
449 return ERROR_OK;
450 }
451
452 int opendous_get_version_info(void)
453 {
454 return ERROR_OK;
455 }
456
457 /***************************************************************************/
458 /* Estick tap functions */
459
460 static int tap_length;
461 static uint8_t tms_buffer[OPENDOUS_TAP_BUFFER_SIZE];
462 static uint8_t tdo_buffer[OPENDOUS_TAP_BUFFER_SIZE];
463
464 struct pending_scan_result {
465 int first; /* First bit position in tdo_buffer to read */
466 int length; /* Number of bits to read */
467 struct scan_command *command; /* Corresponding scan command */
468 uint8_t *buffer;
469 };
470
471 static int pending_scan_results_length;
472 static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
473
474 static int last_tms;
475
476 void opendous_tap_init(void)
477 {
478 tap_length = 0;
479 pending_scan_results_length = 0;
480 }
481
482 void opendous_tap_ensure_space(int scans, int bits)
483 {
484 int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
485 int available_bits = OPENDOUS_TAP_BUFFER_SIZE / 2 - tap_length;
486
487 if ((scans > available_scans) || (bits > available_bits))
488 opendous_tap_execute();
489 }
490
491 void opendous_tap_append_step(int tms, int tdi)
492 {
493 last_tms = tms;
494 unsigned char _tms = tms ? 1 : 0;
495 unsigned char _tdi = tdi ? 1 : 0;
496
497 opendous_tap_ensure_space(0, 1);
498
499 int tap_index = tap_length / 4;
500 int bits = (tap_length % 4) * 2;
501
502 if (tap_length < OPENDOUS_TAP_BUFFER_SIZE) {
503 if (!bits)
504 tms_buffer[tap_index] = 0;
505
506 tms_buffer[tap_index] |= (_tdi << bits)|(_tms << (bits + 1)) ;
507 tap_length++;
508 } else
509 LOG_ERROR("opendous_tap_append_step, overflow");
510 }
511
512 void opendous_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command)
513 {
514 DEBUG_JTAG_IO("append scan, length = %d", length);
515
516 struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[pending_scan_results_length];
517 int i;
518
519 pending_scan_result->first = tap_length;
520 pending_scan_result->length = length;
521 pending_scan_result->command = command;
522 pending_scan_result->buffer = buffer;
523
524 for (i = 0; i < length; i++)
525 opendous_tap_append_step((i < length-1 ? 0 : 1), (buffer[i / 8] >> (i % 8)) & 1);
526 pending_scan_results_length++;
527 }
528
529 /* Pad and send a tap sequence to the device, and receive the answer.
530 * For the purpose of padding we assume that we are in idle or pause state. */
531 int opendous_tap_execute(void)
532 {
533 int byte_length;
534 int i, j;
535 int result;
536
537 #ifdef _DEBUG_USB_COMMS_
538 int byte_length_out;
539 #endif
540
541 if (tap_length > 0) {
542
543 /* memset(tdo_buffer,0,OPENDOUS_TAP_BUFFER_SIZE); */
544 /* LOG_INFO("OPENDOUS tap execute %d",tap_length); */
545 byte_length = (tap_length + 3) / 4;
546
547 #ifdef _DEBUG_USB_COMMS_
548 byte_length_out = (tap_length + 7) / 8;
549 LOG_DEBUG("opendous is sending %d bytes", byte_length);
550 #endif
551
552 for (j = 0, i = 0; j < byte_length;) {
553
554 int receive;
555 int transmit = byte_length - j;
556 if (transmit > OPENDOUS_MAX_TAP_TRANSMIT) {
557 transmit = OPENDOUS_MAX_TAP_TRANSMIT;
558 receive = (OPENDOUS_MAX_TAP_TRANSMIT) / 2;
559 usb_out_buffer[2] = JTAG_CMD_TAP_OUTPUT;
560 } else {
561 usb_out_buffer[2] = JTAG_CMD_TAP_OUTPUT | ((tap_length % 4) << 4);
562 receive = (transmit + 1) / 2;
563 }
564 usb_out_buffer[0] = (transmit + 1) & 0xff;
565 usb_out_buffer[1] = ((transmit + 1) >> 8) & 0xff;
566
567 memmove(usb_out_buffer + 3, tms_buffer + j, transmit);
568 result = opendous_usb_message(opendous_jtag_handle, 3 + transmit, receive);
569 if (result != receive) {
570 LOG_ERROR("opendous_tap_execute, wrong result %d, expected %d", result, receive);
571 return ERROR_JTAG_QUEUE_FAILED;
572 }
573
574 memmove(tdo_buffer + i, usb_in_buffer, receive);
575 i += receive;
576 j += transmit;
577 }
578
579 #ifdef _DEBUG_USB_COMMS_
580 LOG_DEBUG("opendous tap result %d", byte_length_out);
581 opendous_debug_buffer(tdo_buffer, byte_length_out);
582 #endif
583
584 /* LOG_INFO("eStick tap execute %d",tap_length); */
585 for (i = 0; i < pending_scan_results_length; i++) {
586
587 struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[i];
588 uint8_t *buffer = pending_scan_result->buffer;
589 int length = pending_scan_result->length;
590 int first = pending_scan_result->first;
591 struct scan_command *command = pending_scan_result->command;
592
593 /* Copy to buffer */
594 buf_set_buf(tdo_buffer, first, buffer, 0, length);
595
596 DEBUG_JTAG_IO("pending scan result, length = %d", length);
597
598 #ifdef _DEBUG_USB_COMMS_
599 opendous_debug_buffer(buffer, byte_length_out);
600 #endif
601
602 if (jtag_read_buffer(buffer, command) != ERROR_OK) {
603 opendous_tap_init();
604 return ERROR_JTAG_QUEUE_FAILED;
605 }
606
607 if (pending_scan_result->buffer != NULL)
608 free(pending_scan_result->buffer);
609 }
610
611 opendous_tap_init();
612 }
613
614 return ERROR_OK;
615 }
616
617 /*****************************************************************************/
618 /* Estick USB low-level functions */
619
620 struct opendous_jtag *opendous_usb_open(void)
621 {
622 struct opendous_jtag *result;
623
624 struct jtag_libusb_device_handle *devh;
625 if (jtag_libusb_open(vids, pids, &devh) != ERROR_OK)
626 return NULL;
627
628 jtag_libusb_set_configuration(devh, 0);
629 jtag_libusb_claim_interface(devh, 0);
630
631 result = (struct opendous_jtag *) malloc(sizeof(struct opendous_jtag));
632 result->usb_handle = devh;
633 return result;
634 }
635
636 void opendous_usb_close(struct opendous_jtag *opendous_jtag)
637 {
638 jtag_libusb_close(opendous_jtag->usb_handle);
639 free(opendous_jtag);
640 }
641
642 /* Send a message and receive the reply. */
643 int opendous_usb_message(struct opendous_jtag *opendous_jtag, int out_length, int in_length)
644 {
645 int result;
646
647 result = opendous_usb_write(opendous_jtag, out_length);
648 if (result == out_length) {
649 result = opendous_usb_read(opendous_jtag);
650 if (result == in_length)
651 return result;
652 else {
653 LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)", in_length, result);
654 return -1;
655 }
656 } else {
657 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result);
658 return -1;
659 }
660 }
661
662 /* Write data from out_buffer to USB. */
663 int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length)
664 {
665 int result;
666
667 if (out_length > OPENDOUS_OUT_BUFFER_SIZE) {
668 LOG_ERROR("opendous_jtag_write illegal out_length=%d (max=%d)", out_length, OPENDOUS_OUT_BUFFER_SIZE);
669 return -1;
670 }
671
672 #ifdef _DEBUG_USB_COMMS_
673 LOG_DEBUG("%s: USB write begin", opendous_get_time(time_str));
674 #endif
675 result = jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT, \
676 (char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT);
677 #ifdef _DEBUG_USB_COMMS_
678 LOG_DEBUG("%s: USB write end: %d bytes", opendous_get_time(time_str), result);
679 #endif
680
681 DEBUG_JTAG_IO("opendous_usb_write, out_length = %d, result = %d", out_length, result);
682
683 #ifdef _DEBUG_USB_COMMS_
684 opendous_debug_buffer(usb_out_buffer, out_length);
685 #endif
686 return result;
687 }
688
689 /* Read data from USB into in_buffer. */
690 int opendous_usb_read(struct opendous_jtag *opendous_jtag)
691 {
692 #ifdef _DEBUG_USB_COMMS_
693 LOG_DEBUG("%s: USB read begin", opendous_get_time(time_str));
694 #endif
695 int result = jtag_libusb_bulk_read(opendous_jtag->usb_handle, OPENDOUS_READ_ENDPOINT,
696 (char *)usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT);
697 #ifdef _DEBUG_USB_COMMS_
698 LOG_DEBUG("%s: USB read end: %d bytes", opendous_get_time(time_str), result);
699 #endif
700 DEBUG_JTAG_IO("opendous_usb_read, result = %d", result);
701
702 #ifdef _DEBUG_USB_COMMS_
703 opendous_debug_buffer(usb_in_buffer, result);
704 #endif
705 return result;
706 }
707
708 #ifdef _DEBUG_USB_COMMS_
709 #define BYTES_PER_LINE 16
710
711 void opendous_debug_buffer(uint8_t *buffer, int length)
712 {
713 char line[81];
714 char s[4];
715 int i;
716 int j;
717
718 for (i = 0; i < length; i += BYTES_PER_LINE) {
719 snprintf(line, 5, "%04x", i);
720 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
721 snprintf(s, 4, " %02x", buffer[j]);
722 strcat(line, s);
723 }
724 LOG_DEBUG("%s", line);
725 }
726 }
727
728 char *opendous_get_time(char *str)
729 {
730 struct timeb timebuffer;
731 char *timeline;
732
733 ftime(&timebuffer);
734 timeline = ctime(&(timebuffer.time));
735 snprintf(str, 49, "%.8s.%hu", &timeline[11], timebuffer.millitm);
736 return str;
737 }
738 #endif

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)