opendous: Inhibit unnecessary state transitions
[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_speed(int speed);
90 static int opendous_speed_div(int speed, int *khz);
91 static int opendous_khz(int khz, int *jtag_speed);
92 static int opendous_init(void);
93 static int opendous_quit(void);
94
95 /* Queue command functions */
96 static void opendous_end_state(tap_state_t state);
97 static void opendous_state_move(void);
98 static void opendous_path_move(int num_states, tap_state_t *path);
99 static void opendous_runtest(int num_cycles);
100 static void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer,
101 int scan_size, struct scan_command *command);
102 static void opendous_reset(int trst, int srst);
103 static void opendous_simple_command(uint8_t command, uint8_t _data);
104 static int opendous_get_status(void);
105
106 /* opendous tap buffer functions */
107 static void opendous_tap_init(void);
108 static int opendous_tap_execute(void);
109 static void opendous_tap_ensure_space(int scans, int bits);
110 static void opendous_tap_append_step(int tms, int tdi);
111 static void opendous_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command);
112
113 /* opendous lowlevel functions */
114 struct opendous_jtag {
115 struct jtag_libusb_device_handle *usb_handle;
116 };
117
118 static struct opendous_jtag *opendous_usb_open(void);
119 static void opendous_usb_close(struct opendous_jtag *opendous_jtag);
120 static int opendous_usb_message(struct opendous_jtag *opendous_jtag, int out_length, int in_length);
121 static int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length);
122 static int opendous_usb_read(struct opendous_jtag *opendous_jtag);
123
124 /* helper functions */
125 int opendous_get_version_info(void);
126
127 #ifdef _DEBUG_USB_COMMS_
128 char time_str[50];
129 static void opendous_debug_buffer(uint8_t *buffer, int length);
130 char *opendous_get_time(char *);
131 #endif
132
133 static struct opendous_jtag *opendous_jtag_handle;
134
135 /***************************************************************************/
136 /* External interface implementation */
137
138 COMMAND_HANDLER(opendous_handle_opendous_info_command)
139 {
140 if (opendous_get_version_info() == ERROR_OK) {
141 /* attempt to get status */
142 opendous_get_status();
143 }
144
145 return ERROR_OK;
146 }
147
148 COMMAND_HANDLER(opendous_handle_opendous_hw_jtag_command)
149 {
150 switch (CMD_ARGC) {
151 case 0:
152 command_print(CMD_CTX, "opendous hw jtag %i", opendous_hw_jtag_version);
153 break;
154
155 case 1: {
156 int request_version = atoi(CMD_ARGV[0]);
157 switch (request_version) {
158 case 2:
159 case 3:
160 opendous_hw_jtag_version = request_version;
161 break;
162
163 default:
164 return ERROR_COMMAND_SYNTAX_ERROR;
165 }
166 break;
167 }
168
169 default:
170 return ERROR_COMMAND_SYNTAX_ERROR;
171 }
172
173 return ERROR_OK;
174 }
175
176 static const struct command_registration opendous_command_handlers[] = {
177 {
178 .name = "opendous_info",
179 .handler = &opendous_handle_opendous_info_command,
180 .mode = COMMAND_EXEC,
181 .help = "show opendous info",
182 },
183 {
184 .name = "opendous_hw_jtag",
185 .handler = &opendous_handle_opendous_hw_jtag_command,
186 .mode = COMMAND_EXEC,
187 .help = "access opendous HW JTAG command version",
188 .usage = "[2|3]",
189 },
190 COMMAND_REGISTRATION_DONE
191 };
192
193 struct jtag_interface opendous_interface = {
194 .name = "opendous",
195 .commands = opendous_command_handlers,
196 .execute_queue = opendous_execute_queue,
197 .speed = opendous_speed,
198 .speed_div = opendous_speed_div,
199 .khz = opendous_khz,
200 .init = opendous_init,
201 .quit = opendous_quit,
202 };
203
204 static int opendous_execute_queue(void)
205 {
206 struct jtag_command *cmd = jtag_command_queue;
207 int scan_size;
208 enum scan_type type;
209 uint8_t *buffer;
210
211 while (cmd != NULL) {
212 switch (cmd->type) {
213 case JTAG_RUNTEST:
214 DEBUG_JTAG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, \
215 cmd->cmd.runtest->end_state);
216
217 if (cmd->cmd.runtest->end_state != -1)
218 opendous_end_state(cmd->cmd.runtest->end_state);
219 opendous_runtest(cmd->cmd.runtest->num_cycles);
220 break;
221
222 case JTAG_TLR_RESET:
223 DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
224
225 if (cmd->cmd.statemove->end_state != -1)
226 opendous_end_state(cmd->cmd.statemove->end_state);
227 opendous_state_move();
228 break;
229
230 case JTAG_PATHMOVE:
231 DEBUG_JTAG_IO("pathmove: %i states, end in %i", \
232 cmd->cmd.pathmove->num_states, \
233 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
234
235 opendous_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
236 break;
237
238 case JTAG_SCAN:
239 DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state);
240
241 if (cmd->cmd.scan->end_state != -1)
242 opendous_end_state(cmd->cmd.scan->end_state);
243
244 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
245 DEBUG_JTAG_IO("scan input, length = %d", scan_size);
246
247 #ifdef _DEBUG_USB_COMMS_
248 opendous_debug_buffer(buffer, (scan_size + 7) / 8);
249 #endif
250 type = jtag_scan_type(cmd->cmd.scan);
251 opendous_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan);
252 break;
253
254 case JTAG_RESET:
255 DEBUG_JTAG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
256
257 opendous_tap_execute();
258
259 if (cmd->cmd.reset->trst == 1)
260 tap_set_state(TAP_RESET);
261 opendous_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
262 break;
263
264 case JTAG_SLEEP:
265 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
266 opendous_tap_execute();
267 jtag_sleep(cmd->cmd.sleep->us);
268 break;
269
270 default:
271 LOG_ERROR("BUG: unknown JTAG command type encountered");
272 exit(-1);
273 }
274 cmd = cmd->next;
275 }
276 return opendous_tap_execute();
277 }
278
279 /* Sets speed in kHz. */
280 static int opendous_speed(int speed)
281 {
282 if (speed <= OPENDOUS_MAX_SPEED) {
283 /* one day... */
284 return ERROR_OK;
285 } else
286 LOG_INFO("Requested speed %dkHz exceeds maximum of %dkHz, ignored", speed, OPENDOUS_MAX_SPEED);
287
288 return ERROR_OK;
289 }
290
291 static int opendous_speed_div(int speed, int *khz)
292 {
293 *khz = speed;
294
295 return ERROR_OK;
296 }
297
298 static int opendous_khz(int khz, int *jtag_speed)
299 {
300 *jtag_speed = khz;
301 /* TODO: convert this into delay value for opendous */
302
303 return ERROR_OK;
304 }
305
306 static int opendous_init(void)
307 {
308 int check_cnt;
309
310 opendous_jtag_handle = opendous_usb_open();
311
312 if (opendous_jtag_handle == 0) {
313 LOG_ERROR("Cannot find opendous Interface! Please check connection and permissions.");
314 return ERROR_JTAG_INIT_FAILED;
315 }
316
317 check_cnt = 0;
318 while (check_cnt < 3) {
319 if (opendous_get_version_info() == ERROR_OK) {
320 /* attempt to get status */
321 opendous_get_status();
322 break;
323 }
324
325 check_cnt++;
326 }
327
328 LOG_INFO("opendous JTAG Interface ready");
329
330 opendous_reset(0, 0);
331 opendous_tap_init();
332
333 return ERROR_OK;
334 }
335
336 static int opendous_quit(void)
337 {
338 opendous_usb_close(opendous_jtag_handle);
339 return ERROR_OK;
340 }
341
342 /***************************************************************************/
343 /* Queue command implementations */
344
345 void opendous_end_state(tap_state_t state)
346 {
347 if (tap_is_state_stable(state))
348 tap_set_end_state(state);
349 else {
350 LOG_ERROR("BUG: %i is not a valid end state", state);
351 exit(-1);
352 }
353 }
354
355 /* Goes to the end state. */
356 void opendous_state_move(void)
357 {
358 int i;
359 int tms = 0;
360 uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
361 uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
362
363 for (i = 0; i < tms_scan_bits; i++) {
364 tms = (tms_scan >> i) & 1;
365 opendous_tap_append_step(tms, 0);
366 }
367
368 tap_set_state(tap_get_end_state());
369 }
370
371 void opendous_path_move(int num_states, tap_state_t *path)
372 {
373 int i;
374
375 for (i = 0; i < num_states; i++) {
376 if (path[i] == tap_state_transition(tap_get_state(), false))
377 opendous_tap_append_step(0, 0);
378 else if (path[i] == tap_state_transition(tap_get_state(), true))
379 opendous_tap_append_step(1, 0);
380 else {
381 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
382 tap_state_name(tap_get_state()), tap_state_name(path[i]));
383 exit(-1);
384 }
385
386 tap_set_state(path[i]);
387 }
388
389 tap_set_end_state(tap_get_state());
390 }
391
392 void opendous_runtest(int num_cycles)
393 {
394 int i;
395
396 tap_state_t saved_end_state = tap_get_end_state();
397
398 /* only do a state_move when we're not already in IDLE */
399 if (tap_get_state() != TAP_IDLE) {
400 opendous_end_state(TAP_IDLE);
401 opendous_state_move();
402 }
403
404 /* execute num_cycles */
405 for (i = 0; i < num_cycles; i++)
406 opendous_tap_append_step(0, 0);
407
408 /* finish in end_state */
409 opendous_end_state(saved_end_state);
410 if (tap_get_state() != tap_get_end_state())
411 opendous_state_move();
412 }
413
414 void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command)
415 {
416 tap_state_t saved_end_state;
417
418 opendous_tap_ensure_space(1, scan_size + 8);
419
420 saved_end_state = tap_get_end_state();
421
422 /* Move to appropriate scan state */
423 opendous_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
424
425 if (tap_get_state() != tap_get_end_state())
426 opendous_state_move();
427
428 opendous_end_state(saved_end_state);
429
430 /* Scan */
431 opendous_tap_append_scan(scan_size, buffer, command);
432
433 /* We are in Exit1, go to Pause */
434 opendous_tap_append_step(0, 0);
435
436 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
437
438 if (tap_get_state() != tap_get_end_state())
439 opendous_state_move();
440 }
441
442 void opendous_reset(int trst, int srst)
443 {
444 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
445
446 /* Signals are active low */
447 #if 0
448 if (srst == 0)
449 opendous_simple_command(JTAG_CMD_SET_SRST, 1);
450 else if (srst == 1)
451 opendous_simple_command(JTAG_CMD_SET_SRST, 0);
452
453 if (trst == 0)
454 opendous_simple_command(JTAG_CMD_SET_TRST, 1);
455 else if (trst == 1)
456 opendous_simple_command(JTAG_CMD_SET_TRST, 0);
457 #endif
458
459 srst = srst ? 0 : 1;
460 trst = trst ? 0 : 2;
461 opendous_simple_command(JTAG_CMD_SET_SRST_TRST, srst | trst);
462 }
463
464 void opendous_simple_command(uint8_t command, uint8_t _data)
465 {
466 int result;
467
468 DEBUG_JTAG_IO("0x%02x 0x%02x", command, _data);
469
470 usb_out_buffer[0] = 2;
471 usb_out_buffer[1] = 0;
472 usb_out_buffer[2] = command;
473 usb_out_buffer[3] = _data;
474
475 result = opendous_usb_message(opendous_jtag_handle, 4, 1);
476 if (result != 1)
477 LOG_ERROR("opendous command 0x%02x failed (%d)", command, result);
478 }
479
480 int opendous_get_status(void)
481 {
482 return ERROR_OK;
483 }
484
485 int opendous_get_version_info(void)
486 {
487 return ERROR_OK;
488 }
489
490 /***************************************************************************/
491 /* Estick tap functions */
492
493 static int tap_length;
494 static uint8_t tms_buffer[OPENDOUS_TAP_BUFFER_SIZE];
495 static uint8_t tdo_buffer[OPENDOUS_TAP_BUFFER_SIZE];
496
497 struct pending_scan_result {
498 int first; /* First bit position in tdo_buffer to read */
499 int length; /* Number of bits to read */
500 struct scan_command *command; /* Corresponding scan command */
501 uint8_t *buffer;
502 };
503
504 static int pending_scan_results_length;
505 static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
506
507 static int last_tms;
508
509 void opendous_tap_init(void)
510 {
511 tap_length = 0;
512 pending_scan_results_length = 0;
513 }
514
515 void opendous_tap_ensure_space(int scans, int bits)
516 {
517 int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
518
519 if (scans > available_scans)
520 opendous_tap_execute();
521 }
522
523 void opendous_tap_append_step(int tms, int tdi)
524 {
525 last_tms = tms;
526 unsigned char _tms = tms ? 1 : 0;
527 unsigned char _tdi = tdi ? 1 : 0;
528
529 int tap_index = tap_length / 4;
530 int bits = (tap_length % 4) * 2;
531
532 if (tap_length < OPENDOUS_TAP_BUFFER_SIZE) {
533 if (!bits)
534 tms_buffer[tap_index] = 0;
535
536 tms_buffer[tap_index] |= (_tdi << bits)|(_tms << (bits + 1)) ;
537 tap_length++;
538 } else
539 LOG_ERROR("opendous_tap_append_step, overflow");
540 }
541
542 void opendous_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command)
543 {
544 DEBUG_JTAG_IO("append scan, length = %d", length);
545
546 struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[pending_scan_results_length];
547 int i;
548
549 pending_scan_result->first = tap_length;
550 pending_scan_result->length = length;
551 pending_scan_result->command = command;
552 pending_scan_result->buffer = buffer;
553
554 for (i = 0; i < length; i++)
555 opendous_tap_append_step((i < length-1 ? 0 : 1), (buffer[i / 8] >> (i % 8)) & 1);
556 pending_scan_results_length++;
557 }
558
559 /* Pad and send a tap sequence to the device, and receive the answer.
560 * For the purpose of padding we assume that we are in idle or pause state. */
561 int opendous_tap_execute(void)
562 {
563 int byte_length;
564 int i, j;
565 int result;
566
567 #ifdef _DEBUG_USB_COMMS_
568 int byte_length_out;
569 #endif
570
571 if (tap_length > 0) {
572
573 /* memset(tdo_buffer,0,OPENDOUS_TAP_BUFFER_SIZE); */
574 /* LOG_INFO("OPENDOUS tap execute %d",tap_length); */
575 byte_length = (tap_length + 3) / 4;
576
577 #ifdef _DEBUG_USB_COMMS_
578 byte_length_out = (tap_length + 7) / 8;
579 LOG_DEBUG("opendous is sending %d bytes", byte_length);
580 #endif
581
582 for (j = 0, i = 0; j < byte_length;) {
583
584 int receive;
585 int transmit = byte_length - j;
586 if (transmit > OPENDOUS_MAX_TAP_TRANSMIT) {
587 transmit = OPENDOUS_MAX_TAP_TRANSMIT;
588 receive = (OPENDOUS_MAX_TAP_TRANSMIT) / 2;
589 usb_out_buffer[2] = JTAG_CMD_TAP_OUTPUT;
590 } else {
591 usb_out_buffer[2] = JTAG_CMD_TAP_OUTPUT | ((tap_length % 4) << 4);
592 receive = (transmit + 1) / 2;
593 }
594 usb_out_buffer[0] = (transmit + 1) & 0xff;
595 usb_out_buffer[1] = ((transmit + 1) >> 8) & 0xff;
596
597 memmove(usb_out_buffer + 3, tms_buffer + j, transmit);
598 result = opendous_usb_message(opendous_jtag_handle, 3 + transmit, receive);
599 if (result != receive) {
600 LOG_ERROR("opendous_tap_execute, wrong result %d, expected %d", result, receive);
601 return ERROR_JTAG_QUEUE_FAILED;
602 }
603
604 memmove(tdo_buffer + i, usb_in_buffer, receive);
605 i += receive;
606 j += transmit;
607 }
608
609 #ifdef _DEBUG_USB_COMMS_
610 LOG_DEBUG("opendous tap result %d", byte_length_out);
611 opendous_debug_buffer(tdo_buffer, byte_length_out);
612 #endif
613
614 /* LOG_INFO("eStick tap execute %d",tap_length); */
615 for (i = 0; i < pending_scan_results_length; i++) {
616
617 struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[i];
618 uint8_t *buffer = pending_scan_result->buffer;
619 int length = pending_scan_result->length;
620 int first = pending_scan_result->first;
621 struct scan_command *command = pending_scan_result->command;
622
623 /* Copy to buffer */
624 buf_set_buf(tdo_buffer, first, buffer, 0, length);
625
626 DEBUG_JTAG_IO("pending scan result, length = %d", length);
627
628 #ifdef _DEBUG_USB_COMMS_
629 opendous_debug_buffer(buffer, byte_length_out);
630 #endif
631
632 if (jtag_read_buffer(buffer, command) != ERROR_OK) {
633 opendous_tap_init();
634 return ERROR_JTAG_QUEUE_FAILED;
635 }
636
637 if (pending_scan_result->buffer != NULL)
638 free(pending_scan_result->buffer);
639 }
640
641 opendous_tap_init();
642 }
643
644 return ERROR_OK;
645 }
646
647 /*****************************************************************************/
648 /* Estick USB low-level functions */
649
650 struct opendous_jtag *opendous_usb_open(void)
651 {
652 struct opendous_jtag *result;
653
654 struct jtag_libusb_device_handle *devh;
655 if (jtag_libusb_open(vids, pids, &devh) != ERROR_OK)
656 return NULL;
657
658 jtag_libusb_set_configuration(devh, 0);
659 jtag_libusb_claim_interface(devh, 0);
660
661 result = (struct opendous_jtag *) malloc(sizeof(struct opendous_jtag));
662 result->usb_handle = devh;
663 return result;
664 }
665
666 void opendous_usb_close(struct opendous_jtag *opendous_jtag)
667 {
668 jtag_libusb_close(opendous_jtag->usb_handle);
669 free(opendous_jtag);
670 }
671
672 /* Send a message and receive the reply. */
673 int opendous_usb_message(struct opendous_jtag *opendous_jtag, int out_length, int in_length)
674 {
675 int result;
676
677 result = opendous_usb_write(opendous_jtag, out_length);
678 if (result == out_length) {
679 result = opendous_usb_read(opendous_jtag);
680 if (result == in_length)
681 return result;
682 else {
683 LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)", in_length, result);
684 return -1;
685 }
686 } else {
687 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result);
688 return -1;
689 }
690 }
691
692 /* Write data from out_buffer to USB. */
693 int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length)
694 {
695 int result;
696
697 if (out_length > OPENDOUS_OUT_BUFFER_SIZE) {
698 LOG_ERROR("opendous_jtag_write illegal out_length=%d (max=%d)", out_length, OPENDOUS_OUT_BUFFER_SIZE);
699 return -1;
700 }
701
702 #ifdef _DEBUG_USB_COMMS_
703 LOG_DEBUG("%s: USB write begin", opendous_get_time(time_str));
704 #endif
705 result = jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT, \
706 (char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT);
707 #ifdef _DEBUG_USB_COMMS_
708 LOG_DEBUG("%s: USB write end: %d bytes", opendous_get_time(time_str), result);
709 #endif
710
711 DEBUG_JTAG_IO("opendous_usb_write, out_length = %d, result = %d", out_length, result);
712
713 #ifdef _DEBUG_USB_COMMS_
714 opendous_debug_buffer(usb_out_buffer, out_length);
715 #endif
716 return result;
717 }
718
719 /* Read data from USB into in_buffer. */
720 int opendous_usb_read(struct opendous_jtag *opendous_jtag)
721 {
722 #ifdef _DEBUG_USB_COMMS_
723 LOG_DEBUG("%s: USB read begin", opendous_get_time(time_str));
724 #endif
725 int result = jtag_libusb_bulk_read(opendous_jtag->usb_handle, OPENDOUS_READ_ENDPOINT,
726 (char *)usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT);
727 #ifdef _DEBUG_USB_COMMS_
728 LOG_DEBUG("%s: USB read end: %d bytes", opendous_get_time(time_str), result);
729 #endif
730 DEBUG_JTAG_IO("opendous_usb_read, result = %d", result);
731
732 #ifdef _DEBUG_USB_COMMS_
733 opendous_debug_buffer(usb_in_buffer, result);
734 #endif
735 return result;
736 }
737
738 #ifdef _DEBUG_USB_COMMS_
739 #define BYTES_PER_LINE 16
740
741 void opendous_debug_buffer(uint8_t *buffer, int length)
742 {
743 char line[81];
744 char s[4];
745 int i;
746 int j;
747
748 for (i = 0; i < length; i += BYTES_PER_LINE) {
749 snprintf(line, 5, "%04x", i);
750 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
751 snprintf(s, 4, " %02x", buffer[j]);
752 strcat(line, s);
753 }
754 LOG_DEBUG("%s", line);
755 }
756 }
757
758 char *opendous_get_time(char *str)
759 {
760 struct timeb timebuffer;
761 char *timeline;
762
763 ftime(&timebuffer);
764 timeline = ctime(&(timebuffer.time));
765 snprintf(str, 49, "%.8s.%hu", &timeline[11], timebuffer.millitm);
766 return str;
767 }
768 #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)