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