1 /***************************************************************************
2 * Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net> *
3 * based on Dominic Rath's and Benedikt Sauter's usbprog.c *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
28 #include "replacements.h"
41 #define JLINK_WRITE_ENDPOINT 0x02
42 #define JLINK_READ_ENDPOINT 0x81
44 #define JLINK_USB_TIMEOUT 1000
46 // See Section 1.3.2 of the Segger JLink USB protocol manual
47 #define JLINK_IN_BUFFER_SIZE 2048
48 #define JLINK_OUT_BUFFER_SIZE 2*2048+4
49 #define JLINK_EMU_RESULT_BUFFER_SIZE 64
51 /* Global USB buffers */
52 static u8 usb_in_buffer
[JLINK_IN_BUFFER_SIZE
];
53 static u8 usb_out_buffer
[JLINK_OUT_BUFFER_SIZE
];
54 static u8 usb_emu_result_buffer
[JLINK_EMU_RESULT_BUFFER_SIZE
];
56 /* Constants for JLink command */
57 #define EMU_CMD_VERSION 0x01
58 #define EMU_CMD_SET_SPEED 0x05
59 #define EMU_CMD_GET_STATE 0x07
60 #define EMU_CMD_HW_CLOCK 0xc8
61 #define EMU_CMD_HW_TMS0 0xc9
62 #define EMU_CMD_HW_TMS1 0xca
63 #define EMU_CMD_HW_JTAG3 0xcf
64 #define EMU_CMD_GET_MAX_MEM_BLOCK 0xd4
65 #define EMU_CMD_HW_RESET0 0xdc
66 #define EMU_CMD_HW_RESET1 0xdd
67 #define EMU_CMD_HW_TRST0 0xde
68 #define EMU_CMD_HW_TRST1 0xdf
69 #define EMU_CMD_GET_CAPS 0xe8
71 /* max speed 12MHz v5.0 jlink */
72 #define JLINK_MAX_SPEED 12000
74 /* External interface functions */
75 static int jlink_execute_queue(void);
76 static int jlink_speed(int speed
);
77 static int jlink_speed_div(int speed
, int* khz
);
78 static int jlink_khz(int khz
, int *jtag_speed
);
79 static int jlink_register_commands(struct command_context_s
*cmd_ctx
);
80 static int jlink_init(void);
81 static int jlink_quit(void);
83 /* CLI command handler functions */
84 static int jlink_handle_jlink_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
86 /* Queue command functions */
87 static void jlink_end_state(tap_state_t state
);
88 static void jlink_state_move(void);
89 static void jlink_path_move(int num_states
, tap_state_t
*path
);
90 static void jlink_runtest(int num_cycles
);
91 static void jlink_scan(int ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
, scan_command_t
*command
);
92 static void jlink_reset(int trst
, int srst
);
93 static void jlink_simple_command(u8 command
);
94 static int jlink_get_status(void);
96 /* J-Link tap buffer functions */
97 static void jlink_tap_init(void);
98 static int jlink_tap_execute(void);
99 static void jlink_tap_ensure_space(int scans
, int bits
);
100 static void jlink_tap_append_step(int tms
, int tdi
);
101 static void jlink_tap_append_scan(int length
, u8
*buffer
, scan_command_t
*command
);
103 /* Jlink lowlevel functions */
104 typedef struct jlink_jtag
106 struct usb_dev_handle
* usb_handle
;
109 static jlink_jtag_t
*jlink_usb_open(void);
110 static void jlink_usb_close(jlink_jtag_t
*jlink_jtag
);
111 static int jlink_usb_message(jlink_jtag_t
*jlink_jtag
, int out_length
, int in_length
);
112 static int jlink_usb_write(jlink_jtag_t
*jlink_jtag
, int out_length
);
113 static int jlink_usb_read(jlink_jtag_t
*jlink_jtag
, int expected_size
);
114 static int jlink_usb_read_emu_result(jlink_jtag_t
*jlink_jtag
);
116 /* helper functions */
117 static int jlink_get_version_info(void);
119 #ifdef _DEBUG_USB_COMMS_
120 static void jlink_debug_buffer(u8
*buffer
, int length
);
123 static enum tap_state jlink_last_state
= TAP_RESET
;
125 static jlink_jtag_t
* jlink_jtag_handle
;
127 /***************************************************************************/
128 /* External interface implementation */
130 jtag_interface_t jlink_interface
=
133 .execute_queue
= jlink_execute_queue
,
134 .speed
= jlink_speed
,
135 .speed_div
= jlink_speed_div
,
137 .register_commands
= jlink_register_commands
,
142 static void jlink_execute_end_state(jtag_command_t
*cmd
)
144 DEBUG_JTAG_IO("end_state: %i", cmd
->cmd
.end_state
->end_state
);
146 if (cmd
->cmd
.end_state
->end_state
!= TAP_INVALID
)
147 jlink_end_state(cmd
->cmd
.end_state
->end_state
);
150 static void jlink_execute_runtest(jtag_command_t
*cmd
)
152 DEBUG_JTAG_IO("runtest %i cycles, end in %i",
153 cmd
->cmd
.runtest
->num_cycles
,
154 cmd
->cmd
.runtest
->end_state
);
156 if (cmd
->cmd
.runtest
->end_state
!= TAP_INVALID
)
157 jlink_end_state(cmd
->cmd
.runtest
->end_state
);
159 jlink_runtest(cmd
->cmd
.runtest
->num_cycles
);
162 static void jlink_execute_statemove(jtag_command_t
*cmd
)
164 DEBUG_JTAG_IO("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
166 if (cmd
->cmd
.statemove
->end_state
!= TAP_INVALID
)
168 jlink_end_state(cmd
->cmd
.statemove
->end_state
);
173 static void jlink_execute_pathmove(jtag_command_t
*cmd
)
175 DEBUG_JTAG_IO("pathmove: %i states, end in %i",
176 cmd
->cmd
.pathmove
->num_states
,
177 cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
179 jlink_path_move(cmd
->cmd
.pathmove
->num_states
,
180 cmd
->cmd
.pathmove
->path
);
183 static void jlink_execute_scan(jtag_command_t
*cmd
)
189 DEBUG_JTAG_IO("scan end in %s", tap_state_name(cmd
->cmd
.scan
->end_state
));
191 if (cmd
->cmd
.scan
->end_state
!= TAP_INVALID
)
192 jlink_end_state(cmd
->cmd
.scan
->end_state
);
194 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
195 DEBUG_JTAG_IO("scan input, length = %d", scan_size
);
197 #ifdef _DEBUG_USB_COMMS_
198 jlink_debug_buffer(buffer
, (scan_size
+ 7) / 8);
200 type
= jtag_scan_type(cmd
->cmd
.scan
);
201 jlink_scan(cmd
->cmd
.scan
->ir_scan
,
202 type
, buffer
, scan_size
, cmd
->cmd
.scan
);
205 static void jlink_execute_reset(jtag_command_t
*cmd
)
207 DEBUG_JTAG_IO("reset trst: %i srst %i",
208 cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
212 if ( (cmd
->cmd
.reset
->trst
== 1) || ( cmd
->cmd
.reset
->srst
&& (jtag_reset_config
& RESET_SRST_PULLS_TRST
) ) )
214 tap_set_state(TAP_RESET
);
217 jlink_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
221 static void jlink_execute_sleep(jtag_command_t
*cmd
)
223 DEBUG_JTAG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
225 jtag_sleep(cmd
->cmd
.sleep
->us
);
228 static void jlink_execute_command(jtag_command_t
*cmd
)
232 case JTAG_END_STATE
: jlink_execute_end_state(cmd
); break;
233 case JTAG_RUNTEST
: jlink_execute_runtest(cmd
); break;
234 case JTAG_STATEMOVE
: jlink_execute_statemove(cmd
); break;
235 case JTAG_PATHMOVE
: jlink_execute_pathmove(cmd
); break;
236 case JTAG_SCAN
: jlink_execute_scan(cmd
); break;
237 case JTAG_RESET
: jlink_execute_reset(cmd
); break;
238 case JTAG_SLEEP
: jlink_execute_sleep(cmd
); break;
240 LOG_ERROR("BUG: unknown JTAG command type encountered");
245 static int jlink_execute_queue(void)
247 jtag_command_t
*cmd
= jtag_command_queue
;
251 jlink_execute_command(cmd
);
255 return jlink_tap_execute();
258 /* Sets speed in kHz. */
259 static int jlink_speed(int speed
)
263 if (speed
> JLINK_MAX_SPEED
)
265 LOG_INFO("Ignoring speed request: %dkHz exceeds %dkHz maximum",
266 speed
, JLINK_MAX_SPEED
);
270 /* check for RTCK setting */
274 usb_out_buffer
[0] = EMU_CMD_SET_SPEED
;
275 usb_out_buffer
[1] = (speed
>> 0) & 0xff;
276 usb_out_buffer
[2] = (speed
>> 8) & 0xff;
278 result
= jlink_usb_write(jlink_jtag_handle
, 3);
281 LOG_ERROR("J-Link setting speed failed (%d)", result
);
282 return ERROR_JTAG_DEVICE_ERROR
;
288 static int jlink_speed_div(int speed
, int* khz
)
295 static int jlink_khz(int khz
, int *jtag_speed
)
302 static int jlink_register_commands(struct command_context_s
*cmd_ctx
)
304 register_command(cmd_ctx
, NULL
, "jlink_info", jlink_handle_jlink_info_command
, COMMAND_EXEC
,
309 static int jlink_init(void)
313 jlink_jtag_handle
= jlink_usb_open();
315 if (jlink_jtag_handle
== 0)
317 LOG_ERROR("Cannot find jlink Interface! Please check connection and permissions.");
318 return ERROR_JTAG_INIT_FAILED
;
322 while (check_cnt
< 3)
324 if (jlink_get_version_info() == ERROR_OK
)
326 /* attempt to get status */
336 LOG_INFO("J-Link initial read failed, don't worry");
339 LOG_INFO("J-Link JTAG Interface ready");
344 jlink_speed(jtag_speed
);
349 static int jlink_quit(void)
351 jlink_usb_close(jlink_jtag_handle
);
355 /***************************************************************************/
356 /* Queue command implementations */
358 static void jlink_end_state(tap_state_t state
)
360 if (tap_is_state_stable(state
))
362 tap_set_end_state(state
);
366 LOG_ERROR("BUG: %i is not a valid end state", state
);
371 /* Goes to the end state. */
372 static void jlink_state_move(void)
376 u8 tms_scan
= tap_get_tms_path(tap_get_state(), tap_get_end_state());
377 u8 tms_scan_bits
= tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
379 for (i
= 0; i
< tms_scan_bits
; i
++)
381 tms
= (tms_scan
>> i
) & 1;
382 jlink_tap_append_step(tms
, 0);
385 tap_set_state(tap_get_end_state());
388 static void jlink_path_move(int num_states
, tap_state_t
*path
)
392 for (i
= 0; i
< num_states
; i
++)
394 if (path
[i
] == tap_state_transition(tap_get_state(), false))
396 jlink_tap_append_step(0, 0);
398 else if (path
[i
] == tap_state_transition(tap_get_state(), true))
400 jlink_tap_append_step(1, 0);
404 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(path
[i
]));
408 tap_set_state(path
[i
]);
411 tap_set_end_state(tap_get_state());
414 static void jlink_runtest(int num_cycles
)
418 tap_state_t saved_end_state
= tap_get_end_state();
420 /* only do a state_move when we're not already in IDLE */
421 if (tap_get_state() != TAP_IDLE
)
423 jlink_end_state(TAP_IDLE
);
428 /* execute num_cycles */
429 for (i
= 0; i
< num_cycles
; i
++)
431 jlink_tap_append_step(0, 0);
434 /* finish in end_state */
435 jlink_end_state(saved_end_state
);
436 if (tap_get_state() != tap_get_end_state())
442 static void jlink_scan(int ir_scan
, enum scan_type type
, u8
*buffer
, int scan_size
, scan_command_t
*command
)
444 tap_state_t saved_end_state
;
446 jlink_tap_ensure_space(1, scan_size
+ 8);
448 saved_end_state
= tap_get_end_state();
450 /* Move to appropriate scan state */
451 jlink_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
453 /* Only move if we're not already there */
454 if (tap_get_state() != tap_get_end_state())
457 jlink_end_state(saved_end_state
);
460 jlink_tap_append_scan(scan_size
, buffer
, command
);
462 /* We are in Exit1, go to Pause */
463 jlink_tap_append_step(0, 0);
465 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
467 if (tap_get_state() != tap_get_end_state())
473 static void jlink_reset(int trst
, int srst
)
475 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
477 /* Signals are active low */
480 jlink_simple_command(EMU_CMD_HW_RESET1
);
484 jlink_simple_command(EMU_CMD_HW_RESET0
);
489 jlink_simple_command(EMU_CMD_HW_TRST0
);
493 jlink_simple_command(EMU_CMD_HW_TRST1
);
495 jlink_end_state(TAP_RESET
);
500 static void jlink_simple_command(u8 command
)
504 DEBUG_JTAG_IO("0x%02x", command
);
506 usb_out_buffer
[0] = command
;
507 result
= jlink_usb_write(jlink_jtag_handle
, 1);
511 LOG_ERROR("J-Link command 0x%02x failed (%d)", command
, result
);
515 static int jlink_get_status(void)
519 jlink_simple_command(EMU_CMD_GET_STATE
);
521 result
= jlink_usb_read(jlink_jtag_handle
, 8);
524 LOG_ERROR("J-Link command EMU_CMD_GET_STATE failed (%d)\n", result
);
525 return ERROR_JTAG_DEVICE_ERROR
;
528 int vref
= usb_in_buffer
[0] + (usb_in_buffer
[1] << 8);
529 LOG_INFO("Vref = %d.%d TCK = %d TDI = %d TDO = %d TMS = %d SRST = %d TRST = %d\n", \
530 vref
/ 1000, vref
% 1000, \
531 usb_in_buffer
[2], usb_in_buffer
[3], usb_in_buffer
[4], \
532 usb_in_buffer
[5], usb_in_buffer
[6], usb_in_buffer
[7]);
535 LOG_ERROR("Vref too low. Check Target Power\n");
540 static int jlink_get_version_info(void)
544 u32 jlink_caps
, jlink_max_size
;
546 /* query hardware version */
547 jlink_simple_command(EMU_CMD_VERSION
);
549 result
= jlink_usb_read(jlink_jtag_handle
, 2);
552 LOG_ERROR("J-Link command EMU_CMD_VERSION failed (%d)\n", result
);
553 return ERROR_JTAG_DEVICE_ERROR
;
556 len
= buf_get_u32(usb_in_buffer
, 0, 16);
557 result
= jlink_usb_read(jlink_jtag_handle
, len
);
560 LOG_ERROR("J-Link command EMU_CMD_VERSION failed (%d)\n", result
);
561 return ERROR_JTAG_DEVICE_ERROR
;
564 usb_in_buffer
[result
] = 0;
565 LOG_INFO("%s", (char *)usb_in_buffer
);
567 /* query hardware capabilities */
568 jlink_simple_command(EMU_CMD_GET_CAPS
);
570 result
= jlink_usb_read(jlink_jtag_handle
, 4);
573 LOG_ERROR("J-Link command EMU_CMD_GET_CAPS failed (%d)\n", result
);
574 return ERROR_JTAG_DEVICE_ERROR
;
577 jlink_caps
= buf_get_u32(usb_in_buffer
, 0, 32);
578 LOG_INFO("JLink caps 0x%x", jlink_caps
);
581 /* query hardware maximum memory block */
582 jlink_simple_command(EMU_CMD_GET_MAX_MEM_BLOCK
);
584 result
= jlink_usb_read(jlink_jtag_handle
, 4);
587 LOG_ERROR("J-Link command EMU_CMD_GET_MAX_MEM_BLOCK failed (%d)\n", result
);
588 return ERROR_JTAG_DEVICE_ERROR
;
591 jlink_max_size
= buf_get_u32(usb_in_buffer
, 0, 32);
592 LOG_INFO("JLink max mem block %i", jlink_max_size
);
598 static int jlink_handle_jlink_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
600 if (jlink_get_version_info() == ERROR_OK
)
602 /* attempt to get status */
609 /***************************************************************************/
610 /* J-Link tap functions */
612 /* 2048 is the max value we can use here */
613 #define JLINK_TAP_BUFFER_SIZE 1024
615 static unsigned tap_length
=0;
616 static u8 tms_buffer
[JLINK_TAP_BUFFER_SIZE
];
617 static u8 tdi_buffer
[JLINK_TAP_BUFFER_SIZE
];
618 static u8 tdo_buffer
[JLINK_TAP_BUFFER_SIZE
];
622 int first
; /* First bit position in tdo_buffer to read */
623 int length
; /* Number of bits to read */
624 scan_command_t
*command
; /* Corresponding scan command */
626 } pending_scan_result_t
;
628 #define MAX_PENDING_SCAN_RESULTS 256
630 static int pending_scan_results_length
;
631 static pending_scan_result_t pending_scan_results_buffer
[MAX_PENDING_SCAN_RESULTS
];
633 static void jlink_tap_init(void)
636 pending_scan_results_length
= 0;
639 static void jlink_tap_ensure_space(int scans
, int bits
)
641 int available_scans
= MAX_PENDING_SCAN_RESULTS
- pending_scan_results_length
;
642 int available_bits
= JLINK_TAP_BUFFER_SIZE
* 8 - tap_length
- 64;
644 if (scans
> available_scans
|| bits
> available_bits
)
650 static void jlink_tap_append_step(int tms
, int tdi
)
652 int index
= tap_length
/ 8;
654 if (index
>= JLINK_TAP_BUFFER_SIZE
)
656 LOG_ERROR("jlink_tap_append_step: overflow");
660 int bit_index
= tap_length
% 8;
661 u8 bit
= 1 << bit_index
;
663 // we do not pad TMS, so be sure to initialize all bits
666 tms_buffer
[index
] = tdi_buffer
[index
] = 0;
670 tms_buffer
[index
] |= bit
;
672 tms_buffer
[index
] &= ~bit
;
675 tdi_buffer
[index
] |= bit
;
677 tdi_buffer
[index
] &= ~bit
;
682 static void jlink_tap_append_scan(int length
, u8
*buffer
, scan_command_t
*command
)
684 pending_scan_result_t
*pending_scan_result
=
685 &pending_scan_results_buffer
[pending_scan_results_length
];
688 pending_scan_result
->first
= tap_length
;
689 pending_scan_result
->length
= length
;
690 pending_scan_result
->command
= command
;
691 pending_scan_result
->buffer
= buffer
;
693 for (i
= 0; i
< length
; i
++)
695 int tms
= (i
< (length
- 1)) ? 0 : 1;
696 int tdi
= (buffer
[i
/ 8] & (1 << (i
% 8)))!=0;
697 jlink_tap_append_step(tms
, tdi
);
699 pending_scan_results_length
++;
702 /* Pad and send a tap sequence to the device, and receive the answer.
703 * For the purpose of padding we assume that we are in idle or pause state. */
704 static int jlink_tap_execute(void)
713 /* JLink returns an extra NULL in packet when size of in message is a multiple of 64, creates problems with usb comms */
714 /* WARNING This will interfere with tap state counting */
715 while ((TAP_SCAN_BYTES(tap_length
)%64)==0)
717 jlink_tap_append_step((tap_get_state() == TAP_RESET
)?1:0, 0);
720 // number of full bytes (plus one if some would be left over)
721 byte_length
= TAP_SCAN_BYTES(tap_length
);
723 usb_out_buffer
[0] = EMU_CMD_HW_JTAG3
;
724 usb_out_buffer
[1] = 0;
725 usb_out_buffer
[2] = (tap_length
>> 0) & 0xff;
726 usb_out_buffer
[3] = (tap_length
>> 8) & 0xff;
727 memcpy(usb_out_buffer
+ 4, tms_buffer
, byte_length
);
728 memcpy(usb_out_buffer
+ 4 + byte_length
, tdi_buffer
, byte_length
);
730 jlink_last_state
= jtag_debug_state_machine(tms_buffer
, tdi_buffer
,
731 tap_length
, jlink_last_state
);
733 result
= jlink_usb_message(jlink_jtag_handle
, 4 + 2 * byte_length
, byte_length
);
734 if (result
!= byte_length
)
736 LOG_ERROR("jlink_tap_execute, wrong result %d (expected %d)", result
, byte_length
);
738 return ERROR_JTAG_QUEUE_FAILED
;
741 memcpy(tdo_buffer
, usb_in_buffer
, byte_length
);
743 for (i
= 0; i
< pending_scan_results_length
; i
++)
745 pending_scan_result_t
*pending_scan_result
= &pending_scan_results_buffer
[i
];
746 u8
*buffer
= pending_scan_result
->buffer
;
747 int length
= pending_scan_result
->length
;
748 int first
= pending_scan_result
->first
;
749 scan_command_t
*command
= pending_scan_result
->command
;
752 buf_set_buf(tdo_buffer
, first
, buffer
, 0, length
);
754 DEBUG_JTAG_IO("pending scan result, length = %d", length
);
756 #ifdef _DEBUG_USB_COMMS_
757 jlink_debug_buffer(buffer
, byte_length
);
760 if (jtag_read_buffer(buffer
, command
) != ERROR_OK
)
763 return ERROR_JTAG_QUEUE_FAILED
;
766 if (pending_scan_result
->buffer
!= NULL
)
768 free(pending_scan_result
->buffer
);
776 /*****************************************************************************/
777 /* JLink USB low-level functions */
779 static jlink_jtag_t
* jlink_usb_open()
781 struct usb_bus
*busses
;
783 struct usb_device
*dev
;
785 jlink_jtag_t
*result
;
787 result
= (jlink_jtag_t
*) malloc(sizeof(jlink_jtag_t
));
793 busses
= usb_get_busses();
795 /* find jlink_jtag device in usb bus */
797 for (bus
= busses
; bus
; bus
= bus
->next
)
799 for (dev
= bus
->devices
; dev
; dev
= dev
->next
)
801 if ((dev
->descriptor
.idVendor
== VID
) && (dev
->descriptor
.idProduct
== PID
))
803 result
->usb_handle
= usb_open(dev
);
805 /* usb_set_configuration required under win32 */
806 usb_set_configuration(result
->usb_handle
, dev
->config
[0].bConfigurationValue
);
807 usb_claim_interface(result
->usb_handle
, 0);
811 * This makes problems under Mac OS X. And is not needed
812 * under Windows. Hopefully this will not break a linux build
814 usb_set_altinterface(result
->usb_handle
, 0);
825 static void jlink_usb_close(jlink_jtag_t
*jlink_jtag
)
827 usb_close(jlink_jtag
->usb_handle
);
831 /* Send a message and receive the reply. */
832 static int jlink_usb_message(jlink_jtag_t
*jlink_jtag
, int out_length
, int in_length
)
837 result
= jlink_usb_write(jlink_jtag
, out_length
);
838 if (result
!= out_length
)
840 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)",
842 return ERROR_JTAG_DEVICE_ERROR
;
845 result
= jlink_usb_read(jlink_jtag
, in_length
);
846 if ((result
!= in_length
) && (result
!= (in_length
+ 1)))
848 LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
850 return ERROR_JTAG_DEVICE_ERROR
;
853 if (result
== in_length
)
855 /* Must read the result from the EMU too */
856 result2
= jlink_usb_read_emu_result(jlink_jtag
);
859 LOG_ERROR("jlink_usb_read_emu_result retried requested=1, result=%d, in_length=%i", result2
,in_length
);
860 /* Try again once, should only happen if (in_length%64==0) */
861 result2
= jlink_usb_read_emu_result(jlink_jtag
);
864 LOG_ERROR("jlink_usb_read_emu_result failed "
865 "(requested=1, result=%d)", result2
);
866 return ERROR_JTAG_DEVICE_ERROR
;
870 /* Check the result itself */
871 result2
= usb_emu_result_buffer
[0];
875 /* Save the result, then remove it from return value */
876 result2
= usb_in_buffer
[result
--];
881 LOG_ERROR("jlink_usb_message failed with result=%d)", result2
);
882 return ERROR_JTAG_DEVICE_ERROR
;
888 /* calls the given usb_bulk_* function, allowing for the data to trickle in with some timeouts */
889 static int usb_bulk_with_retries(
890 int (*f
)(usb_dev_handle
*, int, char *, int, int),
891 usb_dev_handle
*dev
, int ep
,
892 char *bytes
, int size
, int timeout
)
894 int tries
= 3, count
= 0;
896 while (tries
&& (count
< size
))
898 int result
= f(dev
, ep
, bytes
+ count
, size
- count
, timeout
);
901 else if ((-ETIMEDOUT
!= result
) || !--tries
)
907 static int wrap_usb_bulk_write(usb_dev_handle
*dev
, int ep
,
908 char *buff
, int size
, int timeout
)
910 /* usb_bulk_write() takes const char *buff */
911 return usb_bulk_write(dev
, ep
, buff
, size
, timeout
);
914 static inline int usb_bulk_write_ex(usb_dev_handle
*dev
, int ep
,
915 char *bytes
, int size
, int timeout
)
917 return usb_bulk_with_retries(&wrap_usb_bulk_write
,
918 dev
, ep
, bytes
, size
, timeout
);
921 static inline int usb_bulk_read_ex(usb_dev_handle
*dev
, int ep
,
922 char *bytes
, int size
, int timeout
)
924 return usb_bulk_with_retries(&usb_bulk_read
,
925 dev
, ep
, bytes
, size
, timeout
);
928 /* Write data from out_buffer to USB. */
929 static int jlink_usb_write(jlink_jtag_t
*jlink_jtag
, int out_length
)
933 if (out_length
> JLINK_OUT_BUFFER_SIZE
)
935 LOG_ERROR("jlink_jtag_write illegal out_length=%d (max=%d)", out_length
, JLINK_OUT_BUFFER_SIZE
);
939 result
= usb_bulk_write_ex(jlink_jtag
->usb_handle
, JLINK_WRITE_ENDPOINT
,
940 (char *)usb_out_buffer
, out_length
, JLINK_USB_TIMEOUT
);
942 DEBUG_JTAG_IO("jlink_usb_write, out_length = %d, result = %d", out_length
, result
);
944 #ifdef _DEBUG_USB_COMMS_
945 jlink_debug_buffer(usb_out_buffer
, out_length
);
950 /* Read data from USB into in_buffer. */
951 static int jlink_usb_read(jlink_jtag_t
*jlink_jtag
, int expected_size
)
953 int result
= usb_bulk_read_ex(jlink_jtag
->usb_handle
, JLINK_READ_ENDPOINT
,
954 (char *)usb_in_buffer
, expected_size
, JLINK_USB_TIMEOUT
);
956 DEBUG_JTAG_IO("jlink_usb_read, result = %d", result
);
958 #ifdef _DEBUG_USB_COMMS_
959 jlink_debug_buffer(usb_in_buffer
, result
);
964 /* Read the result from the previous EMU cmd into result_buffer. */
965 static int jlink_usb_read_emu_result(jlink_jtag_t
*jlink_jtag
)
967 int result
= usb_bulk_read_ex(jlink_jtag
->usb_handle
, JLINK_READ_ENDPOINT
,
968 (char *)usb_emu_result_buffer
, 1 /* JLINK_EMU_RESULT_BUFFER_SIZE */,
971 DEBUG_JTAG_IO("jlink_usb_read_result, result = %d", result
);
973 #ifdef _DEBUG_USB_COMMS_
974 jlink_debug_buffer(usb_emu_result_buffer
, result
);
979 #ifdef _DEBUG_USB_COMMS_
980 #define BYTES_PER_LINE 16
982 static void jlink_debug_buffer(u8
*buffer
, int length
)
989 for (i
= 0; i
< length
; i
+= BYTES_PER_LINE
)
991 snprintf(line
, 5, "%04x", i
);
992 for (j
= i
; j
< i
+ BYTES_PER_LINE
&& j
< length
; j
++)
994 snprintf(s
, 4, " %02x", buffer
[j
]);
997 LOG_DEBUG("%s", line
);
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)