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