- added jlink support, based on Jürgen Stuber patch
[openocd.git] / src / jtag / jlink.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net> *
3 * based on Dominic Rath's and Benedikt Sauter's usbprog.c *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "replacements.h"
26
27 #include "jtag.h"
28
29 #include <usb.h>
30 #include <string.h>
31
32 #include "log.h"
33
34 /* enable this to debug communication
35 */
36 #if 0
37 #define _DEBUG_USB_COMMS_
38 #endif
39
40 #ifdef _DEBUG_JTAG_IO_
41 #define DEBUG_JTAG_IO(expr ...) LOG_DEBUG(expr)
42 #else
43 #define DEBUG_JTAG_IO(expr ...)
44 #endif
45
46 #define VID 0x1366
47 #define PID 0x0101
48
49 #define JLINK_WRITE_ENDPOINT 0x02
50 #define JLINK_READ_ENDPOINT 0x81
51
52 #define JLINK_USB_TIMEOUT 100
53
54 #define JLINK_IN_BUFFER_SIZE 2064
55 #define JLINK_OUT_BUFFER_SIZE 2064
56
57 /* Global USB buffers */
58 static u8 usb_in_buffer[JLINK_IN_BUFFER_SIZE];
59 static u8 usb_out_buffer[JLINK_OUT_BUFFER_SIZE];
60
61 /* Constants for JLink command */
62 #define JLINK_FIRMWARE_VERSION 0x01
63 #define JLINK_SPEED_COMMAND 0x05
64 #define JLINK_GET_STATUS_COMMAND 0x07
65 #define JLINK_TAP_SEQUENCE_COMMAND 0xcd
66 #define JLINK_GET_SERIAL 0xe6
67 #define JLINK_SET_SRST_LOW_COMMAND 0xdc
68 #define JLINK_SET_SRST_HIGH_COMMAND 0xdd
69 #define JLINK_SET_TRST_LOW_COMMAND 0xde
70 #define JLINK_SET_TRST_HIGH_COMMAND 0xdf
71 #define JLINK_HARDWARE_VERSION 0xe8
72
73 /* max speed 12MHz v5.0 jlink */
74 #define JLINK_MAX_SPEED 12000
75
76 /* External interface functions */
77 int jlink_execute_queue(void);
78 int jlink_speed(int speed);
79 int jlink_khz(int khz, int *jtag_speed);
80 int jlink_register_commands(struct command_context_s *cmd_ctx);
81 int jlink_init(void);
82 int jlink_quit(void);
83
84 /* CLI command handler functions */
85 int jlink_handle_jlink_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
86
87 /* Queue command functions */
88 void jlink_end_state(enum tap_state state);
89 void jlink_state_move(void);
90 void jlink_path_move(int num_states, enum tap_state *path);
91 void jlink_runtest(int num_cycles);
92 void jlink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, scan_command_t *command);
93 void jlink_reset(int trst, int srst);
94 void jlink_simple_command(u8 command);
95 int jlink_get_status(void);
96
97 /* J-Link tap buffer functions */
98 void jlink_tap_init();
99 int jlink_tap_execute();
100 void jlink_tap_ensure_space(int scans, int bits);
101 void jlink_tap_append_step(int tms, int tdi);
102 void jlink_tap_append_scan(int length, u8 *buffer, scan_command_t *command);
103
104 /* Jlink lowlevel functions */
105 typedef struct jlink_jtag
106 {
107 struct usb_dev_handle* usb_handle;
108 } jlink_jtag_t;
109
110 jlink_jtag_t *jlink_usb_open(void);
111 void jlink_usb_close(jlink_jtag_t *jlink_jtag);
112 int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length);
113 int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length);
114 int jlink_usb_read(jlink_jtag_t *jlink_jtag);
115
116 #ifdef _DEBUG_USB_COMMS_
117 void jlink_debug_buffer(u8 *buffer, int length);
118 #endif
119
120 jlink_jtag_t* jlink_jtag_handle;
121
122 /***************************************************************************/
123 /* External interface implementation */
124
125 jtag_interface_t jlink_interface =
126 {
127 .name = "jlink",
128 .execute_queue = jlink_execute_queue,
129 .speed = jlink_speed,
130 .khz = jlink_khz,
131 .register_commands = jlink_register_commands,
132 .init = jlink_init,
133 .quit = jlink_quit
134 };
135
136 int jlink_execute_queue(void)
137 {
138 jtag_command_t *cmd = jtag_command_queue;
139 int scan_size;
140 enum scan_type type;
141 u8 *buffer;
142
143 while (cmd != NULL)
144 {
145 switch (cmd->type)
146 {
147 case JTAG_END_STATE:
148 DEBUG_JTAG_IO("end_state: %i", cmd->cmd.end_state->end_state);
149
150 if (cmd->cmd.end_state->end_state != -1)
151 {
152 jlink_end_state(cmd->cmd.end_state->end_state);
153 }
154 break;
155
156 case JTAG_RUNTEST:
157 DEBUG_JTAG_IO( "runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, \
158 cmd->cmd.runtest->end_state);
159
160 if (cmd->cmd.runtest->end_state != -1)
161 {
162 jlink_end_state(cmd->cmd.runtest->end_state);
163 }
164 jlink_runtest(cmd->cmd.runtest->num_cycles);
165 break;
166
167 case JTAG_STATEMOVE:
168 DEBUG_JTAG_IO("statemove end in %i",
169 cmd->cmd.statemove->end_state);
170
171 if (cmd->cmd.statemove->end_state != -1)
172 {
173 jlink_end_state(cmd->cmd.statemove->end_state);
174 }
175 jlink_state_move();
176 break;
177
178 case JTAG_PATHMOVE:
179 DEBUG_JTAG_IO("pathmove: %i states, end in %i",
180 cmd->cmd.pathmove->num_states,
181 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
182
183 jlink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
184 break;
185
186 case JTAG_SCAN:
187 DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state);
188
189 if (cmd->cmd.scan->end_state != -1)
190 {
191 jlink_end_state(cmd->cmd.scan->end_state);
192 }
193
194 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
195 DEBUG_JTAG_IO("scan input, length = %d", scan_size);
196
197 #ifdef _DEBUG_USB_COMMS_
198 jlink_debug_buffer(buffer, (scan_size + 7) / 8);
199 #endif
200 type = jtag_scan_type(cmd->cmd.scan);
201 jlink_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan);
202 break;
203
204 case JTAG_RESET:
205 DEBUG_JTAG_IO("reset trst: %i srst %i",
206 cmd->cmd.reset->trst,
207 cmd->cmd.reset->srst);
208
209 jlink_tap_execute();
210
211 if (cmd->cmd.reset->trst == 1)
212 {
213 cur_state = TAP_TLR;
214 }
215 jlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
216 break;
217
218 case JTAG_SLEEP:
219 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
220 jlink_tap_execute();
221 jtag_sleep(cmd->cmd.sleep->us);
222 break;
223
224 default:
225 LOG_ERROR("BUG: unknown JTAG command type encountered");
226 exit(-1);
227 }
228 cmd = cmd->next;
229 }
230 jlink_tap_execute();
231
232 return ERROR_OK;
233 }
234
235 /* Sets speed in kHz. */
236 int jlink_speed(int speed)
237 {
238 int result;
239
240 // if ((speed == -1) || ((1 <= speed) && (speed <= JLINK_MAX_SPEED)))
241 if (speed <= JLINK_MAX_SPEED)
242 {
243 /* check for RTCK setting */
244 if (speed == 0)
245 speed = -1;
246
247 usb_out_buffer[0] = JLINK_SPEED_COMMAND;
248 usb_out_buffer[1] = (speed >> 0) & 0xff;
249 usb_out_buffer[2] = (speed >> 8) & 0xff;
250
251 result = jlink_usb_write(jlink_jtag_handle, 3);
252
253 if (result == 3)
254 {
255 return ERROR_OK;
256 }
257 else
258 {
259 LOG_ERROR("J-Link setting speed failed (%d)", result);
260 return ERROR_JTAG_DEVICE_ERROR;
261 }
262 }
263 else
264 {
265 LOG_INFO("Requested speed %dkHz exceeds maximum of %dkHz, ignored", speed, JLINK_MAX_SPEED);
266 }
267
268 return ERROR_OK;
269 }
270
271 int jlink_khz(int khz, int *jtag_speed)
272 {
273 *jtag_speed = khz;
274
275 return ERROR_OK;
276 }
277
278 int jlink_register_commands(struct command_context_s *cmd_ctx)
279 {
280 register_command(cmd_ctx, NULL, "jlink_info", jlink_handle_jlink_info_command, COMMAND_EXEC,
281 "query jlink info");
282 return ERROR_OK;
283 }
284
285 int jlink_init(void)
286 {
287 int result;
288
289 jlink_jtag_handle = jlink_usb_open();
290
291 if (jlink_jtag_handle == 0)
292 {
293 LOG_ERROR("Can't find USB JTAG Interface! Please check connection and permissions.");
294 return ERROR_JTAG_INIT_FAILED;
295 }
296
297 result = jlink_usb_read(jlink_jtag_handle);
298 if (result != 2 || usb_in_buffer[0] != 0x07 || usb_in_buffer[1] != 0x00)
299 {
300 LOG_INFO("J-Link initial read failed, don't worry");
301 }
302
303 LOG_INFO("J-Link JTAG Interface ready");
304
305 jlink_reset(0, 0);
306 jlink_tap_init();
307
308 /* query jlink status */
309 jlink_get_status();
310
311 return ERROR_OK;
312 }
313
314 int jlink_quit(void)
315 {
316 jlink_usb_close(jlink_jtag_handle);
317 return ERROR_OK;
318 }
319
320 /***************************************************************************/
321 /* Queue command implementations */
322
323 void jlink_end_state(enum tap_state state)
324 {
325 if (tap_move_map[state] != -1)
326 {
327 end_state = state;
328 }
329 else
330 {
331 LOG_ERROR("BUG: %i is not a valid end state", state);
332 exit(-1);
333 }
334 }
335
336 /* Goes to the end state. */
337 void jlink_state_move(void)
338 {
339 int i;
340 int tms = 0;
341 u8 tms_scan = TAP_MOVE(cur_state, end_state);
342
343 for (i = 0; i < 7; i++)
344 {
345 tms = (tms_scan >> i) & 1;
346 jlink_tap_append_step(tms, 0);
347 }
348
349 cur_state = end_state;
350 }
351
352 void jlink_path_move(int num_states, enum tap_state *path)
353 {
354 int i;
355
356 for (i = 0; i < num_states; i++)
357 {
358 if (path[i] == tap_transitions[cur_state].low)
359 {
360 jlink_tap_append_step(0, 0);
361 }
362 else if (path[i] == tap_transitions[cur_state].high)
363 {
364 jlink_tap_append_step(1, 0);
365 }
366 else
367 {
368 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[path[i]]);
369 exit(-1);
370 }
371
372 cur_state = path[i];
373 }
374
375 end_state = cur_state;
376 }
377
378 void jlink_runtest(int num_cycles)
379 {
380 int i;
381
382 enum tap_state saved_end_state = end_state;
383
384 /* only do a state_move when we're not already in RTI */
385 if (cur_state != TAP_RTI)
386 {
387 jlink_end_state(TAP_RTI);
388 jlink_state_move();
389 }
390
391 /* execute num_cycles */
392 for (i = 0; i < num_cycles; i++)
393 {
394 jlink_tap_append_step(0, 0);
395 }
396
397 /* finish in end_state */
398 jlink_end_state(saved_end_state);
399 if (cur_state != end_state)
400 {
401 jlink_state_move();
402 }
403 }
404
405 void jlink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, scan_command_t *command)
406 {
407 enum tap_state saved_end_state;
408
409 jlink_tap_ensure_space(1, scan_size + 8);
410
411 saved_end_state = end_state;
412
413 /* Move to appropriate scan state */
414 jlink_end_state(ir_scan ? TAP_SI : TAP_SD);
415
416 jlink_state_move();
417 jlink_end_state(saved_end_state);
418
419 /* Scan */
420 jlink_tap_append_scan(scan_size, buffer, command);
421
422 /* We are in Exit1, go to Pause */
423 jlink_tap_append_step(0, 0);
424
425 cur_state = ir_scan ? TAP_PI : TAP_PD;
426
427 if (cur_state != end_state)
428 {
429 jlink_state_move();
430 }
431 }
432
433 void jlink_reset(int trst, int srst)
434 {
435 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
436
437 /* Signals are active low */
438 if (trst == 0)
439 {
440 jlink_simple_command(JLINK_SET_TRST_HIGH_COMMAND);
441 }
442 else if (trst == 1)
443 {
444 jlink_simple_command(JLINK_SET_TRST_LOW_COMMAND);
445 }
446
447 if (srst == 0)
448 {
449 jlink_simple_command(JLINK_SET_SRST_HIGH_COMMAND);
450 }
451 else if (srst == 1)
452 {
453 jlink_simple_command(JLINK_SET_SRST_LOW_COMMAND);
454 }
455 }
456
457 void jlink_simple_command(u8 command)
458 {
459 int result;
460
461 DEBUG_JTAG_IO("0x%02x", command);
462
463 usb_out_buffer[0] = command;
464 result = jlink_usb_write(jlink_jtag_handle, 1);
465
466 if (result != 1)
467 {
468 LOG_ERROR("J-Link command 0x%02x failed (%d)", command, result);
469 }
470 }
471
472 int jlink_get_status(void)
473 {
474 int result;
475
476 jlink_simple_command(JLINK_GET_STATUS_COMMAND);
477 result = jlink_usb_read(jlink_jtag_handle);
478
479 if(result == 8)
480 {
481 int vref = usb_in_buffer[0] + (usb_in_buffer[1] << 8);
482 LOG_INFO("Vref = %d.%d TCK=%d TDI=%d TDO=%d TMS=%d SRST=%d TRST=%d\n", \
483 vref / 1000, vref % 1000, \
484 usb_in_buffer[2], usb_in_buffer[3], usb_in_buffer[4], \
485 usb_in_buffer[5], usb_in_buffer[6], usb_in_buffer[7]);
486
487 if(vref < 1500)
488 {
489 LOG_ERROR("Vref too low. Eventually the target isn't powered or disconnected?\n");
490 }
491 }
492 else
493 {
494 LOG_ERROR("J-Link command JLINK_GET_STATUS_COMMAND failed (%d)\n", result);
495 }
496
497 return ERROR_OK;
498 }
499
500 int jlink_handle_jlink_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
501 {
502 int result;
503 int len = 0;
504
505 /* query hardware version */
506 jlink_simple_command(JLINK_FIRMWARE_VERSION);
507 result = jlink_usb_read(jlink_jtag_handle);
508
509 if (result == 2)
510 {
511 len = buf_get_u32(usb_in_buffer, 0, 16);
512 result = jlink_usb_read(jlink_jtag_handle);
513
514 if(result == len)
515 {
516 usb_in_buffer[result] = 0;
517 LOG_INFO(usb_in_buffer);
518 }
519
520 /* attempt to get status */
521 jlink_get_status();
522 }
523 else
524 {
525 LOG_ERROR("J-Link command JLINK_FIRMWARE_VERSION failed (%d)\n", result);
526 }
527
528 return ERROR_OK;
529 }
530
531 /***************************************************************************/
532 /* J-Link tap functions */
533
534 /* We use the maximal value observed */
535 #define JLINK_TAP_BUFFER_SIZE 390
536
537 static int tap_length;
538 static u8 tms_buffer[JLINK_TAP_BUFFER_SIZE];
539 static u8 tdi_buffer[JLINK_TAP_BUFFER_SIZE];
540 static u8 tdo_buffer[JLINK_TAP_BUFFER_SIZE];
541
542 typedef struct
543 {
544 int first; /* First bit position in tdo_buffer to read */
545 int length; /* Number of bits to read */
546 scan_command_t *command; /* Corresponding scan command */
547 u8 *buffer;
548 } pending_scan_result_t;
549
550 #define MAX_PENDING_SCAN_RESULTS 16
551
552 static int pending_scan_results_length;
553 static pending_scan_result_t pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
554
555 static int last_tms;
556
557 void jlink_tap_init()
558 {
559 tap_length = 0;
560 pending_scan_results_length = 0;
561 }
562
563 void jlink_tap_ensure_space(int scans, int bits)
564 {
565 int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
566 int available_bits = JLINK_TAP_BUFFER_SIZE * 8 - tap_length;
567
568 if (scans > available_scans || bits > available_bits)
569 {
570 jlink_tap_execute();
571 }
572 }
573
574 void jlink_tap_append_step(int tms, int tdi)
575 {
576 last_tms = tms;
577 int index = tap_length / 8;
578
579 if (index < JLINK_TAP_BUFFER_SIZE)
580 {
581 int bit_index = tap_length % 8;
582 u8 bit = 1 << bit_index;
583
584 if (tms)
585 {
586 tms_buffer[index] |= bit;
587 }
588 else
589 {
590 tms_buffer[index] &= ~bit;
591 }
592
593 if (tdi)
594 {
595 tdi_buffer[index] |= bit;
596 }
597 else
598 {
599 tdi_buffer[index] &= ~bit;
600 }
601
602 tap_length++;
603 }
604 else
605 {
606 LOG_ERROR("jlink_tap_append_step, overflow");
607 }
608 }
609
610 void jlink_tap_append_scan(int length, u8 *buffer, scan_command_t *command)
611 {
612 pending_scan_result_t *pending_scan_result = &pending_scan_results_buffer[pending_scan_results_length];
613 int i;
614
615 pending_scan_result->first = tap_length;
616 pending_scan_result->length = length;
617 pending_scan_result->command = command;
618 pending_scan_result->buffer = buffer;
619
620 for (i = 0; i < length; i++)
621 {
622 jlink_tap_append_step((i < length-1 ? 0 : 1), (buffer[i/8] >> (i%8)) & 1);
623 }
624 pending_scan_results_length++;
625 }
626
627 /* Pad and send a tap sequence to the device, and receive the answer.
628 * For the purpose of padding we assume that we are in idle or pause state. */
629 int jlink_tap_execute()
630 {
631 int byte_length;
632 int tms_offset;
633 int tdi_offset;
634 int i;
635 int result;
636
637 if (tap_length > 0)
638 {
639 /* Pad last byte so that tap_length is divisible by 8 */
640 while (tap_length % 8 != 0)
641 {
642 /* More of the last TMS value keeps us in the same state,
643 * analogous to free-running JTAG interfaces. */
644 jlink_tap_append_step(last_tms, 0);
645 }
646
647 byte_length = tap_length / 8;
648
649 usb_out_buffer[0] = JLINK_TAP_SEQUENCE_COMMAND;
650 usb_out_buffer[1] = (tap_length >> 0) & 0xff;
651 usb_out_buffer[2] = (tap_length >> 8) & 0xff;
652
653 tms_offset = 3;
654 for (i = 0; i < byte_length; i++)
655 {
656 usb_out_buffer[tms_offset + i] = tms_buffer[i];
657 }
658
659 tdi_offset = tms_offset + byte_length;
660 for (i = 0; i < byte_length; i++)
661 {
662 usb_out_buffer[tdi_offset + i] = tdi_buffer[i];
663 }
664
665 result = jlink_usb_message(jlink_jtag_handle, 3 + 2 * byte_length, byte_length);
666
667 if (result == byte_length)
668 {
669 for (i = 0; i < byte_length; i++)
670 {
671 tdo_buffer[i] = usb_in_buffer[i];
672 }
673
674 for (i = 0; i < pending_scan_results_length; i++)
675 {
676 pending_scan_result_t *pending_scan_result = &pending_scan_results_buffer[i];
677 u8 *buffer = pending_scan_result->buffer;
678 int length = pending_scan_result->length;
679 int first = pending_scan_result->first;
680 scan_command_t *command = pending_scan_result->command;
681
682 /* Copy to buffer */
683 buf_set_buf(tdo_buffer, first, buffer, 0, length);
684
685 DEBUG_JTAG_IO("pending scan result, length = %d", length);
686
687 #ifdef _DEBUG_USB_COMMS_
688 jlink_debug_buffer(buffer, byte_length);
689 #endif
690
691 if (jtag_read_buffer(buffer, command) != ERROR_OK)
692 {
693 jlink_tap_init();
694 return ERROR_JTAG_QUEUE_FAILED;
695 }
696
697 if (pending_scan_result->buffer != NULL)
698 {
699 free(pending_scan_result->buffer);
700 }
701 }
702 }
703 else
704 {
705 LOG_ERROR("jlink_tap_execute, wrong result %d, expected %d", result, byte_length);
706 return ERROR_JTAG_QUEUE_FAILED;
707 }
708
709 jlink_tap_init();
710 }
711
712 return ERROR_OK;
713 }
714
715 /*****************************************************************************/
716 /* JLink USB low-level functions */
717
718 jlink_jtag_t* jlink_usb_open()
719 {
720 struct usb_bus *busses;
721 struct usb_bus *bus;
722 struct usb_device *dev;
723
724 jlink_jtag_t *result;
725
726 result = (jlink_jtag_t*) malloc(sizeof(jlink_jtag_t));
727
728 usb_init();
729 usb_find_busses();
730 usb_find_devices();
731
732 busses = usb_get_busses();
733
734 /* find jlink_jtag device in usb bus */
735
736 for (bus = busses; bus; bus = bus->next)
737 {
738 for (dev = bus->devices; dev; dev = dev->next)
739 {
740 if ((dev->descriptor.idVendor == VID) && (dev->descriptor.idProduct == PID))
741 {
742 result->usb_handle = usb_open(dev);
743
744 /* usb_set_configuration required under win32 */
745 usb_set_configuration(result->usb_handle, dev->config[0].bConfigurationValue);
746 usb_claim_interface(result->usb_handle, 0);
747 usb_set_altinterface(result->usb_handle, 0);
748 return result;
749 }
750 }
751 }
752
753 free(result);
754 return NULL;
755 }
756
757 void jlink_usb_close(jlink_jtag_t *jlink_jtag)
758 {
759 usb_close(jlink_jtag->usb_handle);
760 free(jlink_jtag);
761 }
762
763 /* Send a message and receive the reply. */
764 int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length)
765 {
766 int result;
767
768 result = jlink_usb_write(jlink_jtag, out_length);
769 if (result == out_length)
770 {
771 result = jlink_usb_read(jlink_jtag);
772 if (result == in_length)
773 {
774 return result;
775 }
776 else
777 {
778 LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)", in_length, result);
779 return -1;
780 }
781 }
782 else
783 {
784 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result);
785 return -1;
786 }
787 }
788
789 /* Write data from out_buffer to USB. */
790 int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length)
791 {
792 int result;
793
794 if (out_length > JLINK_OUT_BUFFER_SIZE)
795 {
796 LOG_ERROR("jlink_jtag_write illegal out_length=%d (max=%d)", out_length, JLINK_OUT_BUFFER_SIZE);
797 return -1;
798 }
799
800 result = usb_bulk_write(jlink_jtag->usb_handle, JLINK_WRITE_ENDPOINT, \
801 usb_out_buffer, out_length, JLINK_USB_TIMEOUT);
802
803 DEBUG_JTAG_IO("jlink_usb_write, out_length = %d, result = %d", out_length, result);
804
805 #ifdef _DEBUG_USB_COMMS_
806 jlink_debug_buffer(usb_out_buffer, out_length);
807 #endif
808 return result;
809 }
810
811 /* Read data from USB into in_buffer. */
812 int jlink_usb_read(jlink_jtag_t *jlink_jtag)
813 {
814 int result = usb_bulk_read(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT, \
815 usb_in_buffer, JLINK_IN_BUFFER_SIZE, JLINK_USB_TIMEOUT);
816
817 DEBUG_JTAG_IO("jlink_usb_read, result = %d", result);
818
819 #ifdef _DEBUG_USB_COMMS_
820 jlink_debug_buffer(usb_in_buffer, result);
821 #endif
822 return result;
823 }
824
825 #ifdef _DEBUG_USB_COMMS_
826 #define BYTES_PER_LINE 16
827
828 void jlink_debug_buffer(u8 *buffer, int length)
829 {
830 char line[81];
831 char s[4];
832 int i;
833 int j;
834
835 for (i = 0; i < length; i += BYTES_PER_LINE)
836 {
837 snprintf(line, 5, "%04x", i);
838 for (j = i; j < i + BYTES_PER_LINE && j < length; j++)
839 {
840 snprintf(s, 4, " %02x", buffer[j]);
841 strcat(line, s);
842 }
843 LOG_DEBUG(line);
844 }
845 }
846 #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)