1 /***************************************************************************
2 * Copyright (C) 2009 by Dimitar Dimitrov <dinuxbg@gmail.com> *
3 * based on Dominic Rath's and Benedikt Sauter's usbprog.c *
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. *
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. *
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 ***************************************************************************/
25 #include "interface.h"
30 #define USB_VID 0x15ba
31 #define USB_PID 0x001e
33 #define ARMJTAGEW_EPT_BULK_OUT 0x01u
34 #define ARMJTAGEW_EPT_BULK_IN 0x82u
36 #define ARMJTAGEW_USB_TIMEOUT 2000
38 #define ARMJTAGEW_IN_BUFFER_SIZE (4*1024)
39 #define ARMJTAGEW_OUT_BUFFER_SIZE (4*1024)
42 /* USB command request codes. */
43 #define CMD_GET_VERSION 0x00
44 #define CMD_SELECT_DPIMPL 0x10
45 #define CMD_SET_TCK_FREQUENCY 0x11
46 #define CMD_GET_TCK_FREQUENCY 0x12
47 #define CMD_MEASURE_MAX_TCK_FREQ 0x15
48 #define CMD_MEASURE_RTCK_RESPONSE 0x16
49 #define CMD_TAP_SHIFT 0x17
50 #define CMD_SET_TAPHW_STATE 0x20
51 #define CMD_GET_TAPHW_STATE 0x21
52 #define CMD_TGPWR_SETUP 0x22
54 /* Global USB buffers */
55 static uint8_t usb_in_buffer
[ARMJTAGEW_IN_BUFFER_SIZE
];
56 static uint8_t usb_out_buffer
[ARMJTAGEW_OUT_BUFFER_SIZE
];
58 /* External interface functions */
59 static int armjtagew_execute_queue(void);
60 static int armjtagew_speed(int speed
);
61 static int armjtagew_khz(int khz
, int *jtag_speed
);
62 static int armjtagew_register_commands(struct command_context_s
*cmd_ctx
);
63 static int armjtagew_init(void);
64 static int armjtagew_quit(void);
66 /* CLI command handler functions */
67 static int armjtagew_handle_armjtagew_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
69 /* Queue command functions */
70 static void armjtagew_end_state(tap_state_t state
);
71 static void armjtagew_state_move(void);
72 static void armjtagew_path_move(int num_states
, tap_state_t
*path
);
73 static void armjtagew_runtest(int num_cycles
);
74 static void armjtagew_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
, int scan_size
, struct scan_command
*command
);
75 static void armjtagew_reset(int trst
, int srst
);
76 //static void armjtagew_simple_command(uint8_t command);
77 static int armjtagew_get_status(void);
79 /* tap buffer functions */
80 static void armjtagew_tap_init(void);
81 static int armjtagew_tap_execute(void);
82 static void armjtagew_tap_ensure_space(int scans
, int bits
);
83 static void armjtagew_tap_append_step(int tms
, int tdi
);
84 static void armjtagew_tap_append_scan(int length
, uint8_t *buffer
, struct scan_command
*command
);
86 /* ARM-JTAG-EW lowlevel functions */
88 struct usb_dev_handle
* usb_handle
;
91 static struct armjtagew
*armjtagew_usb_open(void);
92 static void armjtagew_usb_close(struct armjtagew
*armjtagew
);
93 static int armjtagew_usb_message(struct armjtagew
*armjtagew
, int out_length
, int in_length
);
94 static int armjtagew_usb_write(struct armjtagew
*armjtagew
, int out_length
);
95 static int armjtagew_usb_read(struct armjtagew
*armjtagew
, int exp_in_length
);
97 /* helper functions */
98 static int armjtagew_get_version_info(void);
100 #ifdef _DEBUG_USB_COMMS_
101 static void armjtagew_debug_buffer(uint8_t *buffer
, int length
);
104 static struct armjtagew
* armjtagew_handle
;
108 /***************************************************************************/
109 /* External interface implementation */
111 struct jtag_interface armjtagew_interface
=
113 .name
= "arm-jtag-ew",
114 .execute_queue
= armjtagew_execute_queue
,
115 .speed
= armjtagew_speed
,
116 .khz
= armjtagew_khz
,
117 .register_commands
= armjtagew_register_commands
,
118 .init
= armjtagew_init
,
119 .quit
= armjtagew_quit
123 static int armjtagew_execute_queue(void)
125 jtag_command_t
*cmd
= jtag_command_queue
;
135 DEBUG_JTAG_IO("runtest %i cycles, end in %i", cmd
->cmd
.runtest
->num_cycles
, \
136 cmd
->cmd
.runtest
->end_state
);
138 armjtagew_end_state(cmd
->cmd
.runtest
->end_state
);
139 armjtagew_runtest(cmd
->cmd
.runtest
->num_cycles
);
143 DEBUG_JTAG_IO("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
145 armjtagew_end_state(cmd
->cmd
.statemove
->end_state
);
146 armjtagew_state_move();
150 DEBUG_JTAG_IO("pathmove: %i states, end in %i", \
151 cmd
->cmd
.pathmove
->num_states
, \
152 cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
154 armjtagew_path_move(cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
);
158 DEBUG_JTAG_IO("scan end in %i", cmd
->cmd
.scan
->end_state
);
160 armjtagew_end_state(cmd
->cmd
.scan
->end_state
);
162 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
163 DEBUG_JTAG_IO("scan input, length = %d", scan_size
);
165 #ifdef _DEBUG_USB_COMMS_
166 armjtagew_debug_buffer(buffer
, (scan_size
+ 7) / 8);
168 type
= jtag_scan_type(cmd
->cmd
.scan
);
169 armjtagew_scan(cmd
->cmd
.scan
->ir_scan
, type
, buffer
, scan_size
, cmd
->cmd
.scan
);
173 DEBUG_JTAG_IO("reset trst: %i srst %i", cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
175 armjtagew_tap_execute();
177 if (cmd
->cmd
.reset
->trst
== 1)
179 tap_set_state(TAP_RESET
);
181 armjtagew_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
185 DEBUG_JTAG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
186 armjtagew_tap_execute();
187 jtag_sleep(cmd
->cmd
.sleep
->us
);
191 LOG_ERROR("BUG: unknown JTAG command type encountered");
197 return armjtagew_tap_execute();
201 /* Sets speed in kHz. */
202 static int armjtagew_speed(int speed
)
208 usb_out_buffer
[0] = CMD_SET_TCK_FREQUENCY
;
209 buf_set_u32(usb_out_buffer
+ 1, 0, 32, speed
);
211 result
= armjtagew_usb_message(armjtagew_handle
, 4, 4);
215 LOG_ERROR("ARM-JTAG-EW setting speed failed (%d)", result
);
216 return ERROR_JTAG_DEVICE_ERROR
;
219 usb_out_buffer
[0] = CMD_GET_TCK_FREQUENCY
;
220 result
= armjtagew_usb_message(armjtagew_handle
, 1, 4);
221 speed_real
= (int)buf_get_u32(usb_in_buffer
,0,32);
224 LOG_ERROR("ARM-JTAG-EW getting speed failed (%d)", result
);
225 return ERROR_JTAG_DEVICE_ERROR
;
229 LOG_INFO("Requested speed %dkHz, emulator reported %dkHz.", speed
, speed_real
);
236 static int armjtagew_khz(int khz
, int *jtag_speed
)
243 static int armjtagew_register_commands(struct command_context_s
*cmd_ctx
)
245 register_command(cmd_ctx
, NULL
, "armjtagew_info", armjtagew_handle_armjtagew_info_command
, COMMAND_EXEC
,
246 "query armjtagew info");
250 static int armjtagew_init(void)
254 armjtagew_handle
= armjtagew_usb_open();
256 if (armjtagew_handle
== 0)
258 LOG_ERROR("Cannot find ARM-JTAG-EW Interface! Please check connection and permissions.");
259 return ERROR_JTAG_INIT_FAILED
;
263 while (check_cnt
< 3)
265 if (armjtagew_get_version_info() == ERROR_OK
)
267 /* attempt to get status */
268 armjtagew_get_status();
277 LOG_INFO("ARM-JTAG-EW initial read failed, don't worry");
280 LOG_INFO("ARM-JTAG-EW JTAG Interface ready");
282 armjtagew_reset(0, 0);
283 armjtagew_tap_init();
288 static int armjtagew_quit(void)
290 armjtagew_usb_close(armjtagew_handle
);
294 /***************************************************************************/
295 /* Queue command implementations */
297 static void armjtagew_end_state(tap_state_t state
)
299 if (tap_is_state_stable(state
))
301 tap_set_end_state(state
);
305 LOG_ERROR("BUG: %i is not a valid end state", state
);
310 /* Goes to the end state. */
311 static void armjtagew_state_move(void)
315 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(), tap_get_end_state());
316 int tms_count
= tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
318 for (i
= 0; i
< tms_count
; i
++)
320 tms
= (tms_scan
>> i
) & 1;
321 armjtagew_tap_append_step(tms
, 0);
324 tap_set_state(tap_get_end_state());
327 static void armjtagew_path_move(int num_states
, tap_state_t
*path
)
331 for (i
= 0; i
< num_states
; i
++)
334 * TODO: The ARM-JTAG-EW hardware delays TDI with 3 TCK cycles when in RTCK mode.
335 * Either handle that here, or update the documentation with examples
336 * how to fix that in the configuration files.
338 if (path
[i
] == tap_state_transition(tap_get_state(), false))
340 armjtagew_tap_append_step(0, 0);
342 else if (path
[i
] == tap_state_transition(tap_get_state(), true))
344 armjtagew_tap_append_step(1, 0);
348 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(path
[i
]));
352 tap_set_state(path
[i
]);
355 tap_set_end_state(tap_get_state());
358 static void armjtagew_runtest(int num_cycles
)
362 tap_state_t saved_end_state
= tap_get_end_state();
364 /* only do a state_move when we're not already in IDLE */
365 if (tap_get_state() != TAP_IDLE
)
367 armjtagew_end_state(TAP_IDLE
);
368 armjtagew_state_move();
371 /* execute num_cycles */
372 for (i
= 0; i
< num_cycles
; i
++)
374 armjtagew_tap_append_step(0, 0);
377 /* finish in end_state */
378 armjtagew_end_state(saved_end_state
);
379 if (tap_get_state() != tap_get_end_state())
381 armjtagew_state_move();
385 static void armjtagew_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
, int scan_size
, struct scan_command
*command
)
387 tap_state_t saved_end_state
;
389 armjtagew_tap_ensure_space(1, scan_size
+ 8);
391 saved_end_state
= tap_get_end_state();
393 /* Move to appropriate scan state */
394 armjtagew_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
396 armjtagew_state_move();
397 armjtagew_end_state(saved_end_state
);
400 armjtagew_tap_append_scan(scan_size
, buffer
, command
);
402 /* We are in Exit1, go to Pause */
403 armjtagew_tap_append_step(0, 0);
405 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
407 if (tap_get_state() != tap_get_end_state())
409 armjtagew_state_move();
413 static void armjtagew_reset(int trst
, int srst
)
415 const uint8_t trst_mask
= (1u << 5);
416 const uint8_t srst_mask
= (1u << 6);
419 uint8_t change_mask
= 0;
422 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
427 outp_en
&= ~srst_mask
; /* tristate */
428 change_mask
|= srst_mask
;
433 outp_en
|= srst_mask
;
434 change_mask
|= srst_mask
;
440 outp_en
&= ~trst_mask
; /* tristate */
441 change_mask
|= trst_mask
;
446 outp_en
|= trst_mask
;
447 change_mask
|= trst_mask
;
450 usb_out_buffer
[0] = CMD_SET_TAPHW_STATE
;
451 usb_out_buffer
[1] = val
;
452 usb_out_buffer
[2] = outp_en
;
453 usb_out_buffer
[3] = change_mask
;
454 result
= armjtagew_usb_write(armjtagew_handle
, 4);
457 LOG_ERROR("ARM-JTAG-EW TRST/SRST pin set failed failed (%d)", result
);
462 static int armjtagew_get_status(void)
466 usb_out_buffer
[0] = CMD_GET_TAPHW_STATE
;
467 result
= armjtagew_usb_message(armjtagew_handle
, 1, 12);
471 unsigned int u_tg
= buf_get_u32(usb_in_buffer
, 0, 16);
472 LOG_INFO("U_tg = %d mV, U_aux = %d mV, U_tgpwr = %d mV, I_tgpwr = %d mA, D1 = %d, Target power %s %s\n",
473 (int)(buf_get_u32(usb_in_buffer
+ 0, 0, 16)),
474 (int)(buf_get_u32(usb_in_buffer
+ 2, 0, 16)),
475 (int)(buf_get_u32(usb_in_buffer
+ 4, 0, 16)),
476 (int)(buf_get_u32(usb_in_buffer
+ 6, 0, 16)),
478 usb_in_buffer
[11] ? "OVERCURRENT" : "OK",
479 usb_in_buffer
[10] ? "enabled" : "disabled");
483 LOG_ERROR("Vref too low. Check Target Power\n");
488 LOG_ERROR("ARM-JTAG-EW command CMD_GET_TAPHW_STATE failed (%d)\n", result
);
494 static int armjtagew_get_version_info(void)
500 /* query hardware version */
501 usb_out_buffer
[0] = CMD_GET_VERSION
;
502 result
= armjtagew_usb_message(armjtagew_handle
, 1, 4 + 15 + 256);
506 LOG_ERROR("ARM-JTAG-EW command CMD_GET_VERSION failed (%d)\n", result
);
507 return ERROR_JTAG_DEVICE_ERROR
;
511 memcpy(sn
, usb_in_buffer
+ 4, 15);
513 memcpy(auxinfo
, usb_in_buffer
+ 4+15, 256);
516 LOG_INFO("ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s", \
517 usb_in_buffer
[1], usb_in_buffer
[0], \
518 isgraph(usb_in_buffer
[2]) ? usb_in_buffer
[2] : 'X', \
523 static int armjtagew_handle_armjtagew_info_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
525 if (armjtagew_get_version_info() == ERROR_OK
)
527 /* attempt to get status */
528 armjtagew_get_status();
534 /***************************************************************************/
535 /* ARM-JTAG-EW tap functions */
537 /* 2048 is the max value we can use here */
538 #define ARMJTAGEW_TAP_BUFFER_SIZE 2048
540 static int tap_length
;
541 static uint8_t tms_buffer
[ARMJTAGEW_TAP_BUFFER_SIZE
];
542 static uint8_t tdi_buffer
[ARMJTAGEW_TAP_BUFFER_SIZE
];
543 static uint8_t tdo_buffer
[ARMJTAGEW_TAP_BUFFER_SIZE
];
545 struct pending_scan_result
{
546 int first
; /* First bit position in tdo_buffer to read */
547 int length
; /* Number of bits to read */
548 struct scan_command
*command
; /* Corresponding scan command */
552 #define MAX_PENDING_SCAN_RESULTS 256
554 static int pending_scan_results_length
;
555 static struct pending_scan_result pending_scan_results_buffer
[MAX_PENDING_SCAN_RESULTS
];
559 static void armjtagew_tap_init(void)
562 pending_scan_results_length
= 0;
565 static void armjtagew_tap_ensure_space(int scans
, int bits
)
567 int available_scans
= MAX_PENDING_SCAN_RESULTS
- pending_scan_results_length
;
568 int available_bits
= ARMJTAGEW_TAP_BUFFER_SIZE
* 8 - tap_length
;
570 if (scans
> available_scans
|| bits
> available_bits
)
572 armjtagew_tap_execute();
576 static void armjtagew_tap_append_step(int tms
, int tdi
)
579 int index
= tap_length
/ 8;
581 if (index
< ARMJTAGEW_TAP_BUFFER_SIZE
)
583 int bit_index
= tap_length
% 8;
584 uint8_t bit
= 1 << bit_index
;
588 tms_buffer
[index
] |= bit
;
592 tms_buffer
[index
] &= ~bit
;
597 tdi_buffer
[index
] |= bit
;
601 tdi_buffer
[index
] &= ~bit
;
608 LOG_ERROR("armjtagew_tap_append_step, overflow");
612 void armjtagew_tap_append_scan(int length
, uint8_t *buffer
, struct scan_command
*command
)
614 struct pending_scan_result
*pending_scan_result
= &pending_scan_results_buffer
[pending_scan_results_length
];
617 pending_scan_result
->first
= tap_length
;
618 pending_scan_result
->length
= length
;
619 pending_scan_result
->command
= command
;
620 pending_scan_result
->buffer
= buffer
;
622 for (i
= 0; i
< length
; i
++)
624 armjtagew_tap_append_step((i
< length
-1 ? 0 : 1), (buffer
[i
/8] >> (i
%8)) & 1);
626 pending_scan_results_length
++;
629 /* Pad and send a tap sequence to the device, and receive the answer.
630 * For the purpose of padding we assume that we are in idle or pause state. */
631 static int armjtagew_tap_execute(void)
641 /* Pad last byte so that tap_length is divisible by 8 */
642 while (tap_length
% 8 != 0)
644 /* More of the last TMS value keeps us in the same state,
645 * analogous to free-running JTAG interfaces. */
646 armjtagew_tap_append_step(last_tms
, 0);
649 byte_length
= tap_length
/ 8;
651 usb_out_buffer
[0] = CMD_TAP_SHIFT
;
652 buf_set_u32(usb_out_buffer
+ 1, 0, 16, byte_length
);
655 for (i
= 0; i
< byte_length
; i
++)
657 usb_out_buffer
[tms_offset
+ i
] = flip_u32(tms_buffer
[i
],8);
660 tdi_offset
= tms_offset
+ byte_length
;
661 for (i
= 0; i
< byte_length
; i
++)
663 usb_out_buffer
[tdi_offset
+ i
] = flip_u32(tdi_buffer
[i
],8);
666 result
= armjtagew_usb_message(armjtagew_handle
, 3 + 2 * byte_length
, byte_length
+ 4);
672 stat
= (int)buf_get_u32(usb_in_buffer
+ byte_length
, 0, 32);
674 LOG_ERROR("armjtagew_tap_execute, emulator returned error code %d for a CMD_TAP_SHIFT command", stat
);
675 return ERROR_JTAG_QUEUE_FAILED
;
678 for (i
= 0; i
< byte_length
; i
++)
680 tdo_buffer
[i
] = flip_u32(usb_in_buffer
[i
],8);
683 for (i
= 0; i
< pending_scan_results_length
; i
++)
685 struct pending_scan_result
*pending_scan_result
= &pending_scan_results_buffer
[i
];
686 uint8_t *buffer
= pending_scan_result
->buffer
;
687 int length
= pending_scan_result
->length
;
688 int first
= pending_scan_result
->first
;
689 struct scan_command
*command
= pending_scan_result
->command
;
692 buf_set_buf(tdo_buffer
, first
, buffer
, 0, length
);
694 DEBUG_JTAG_IO("pending scan result, length = %d", length
);
696 #ifdef _DEBUG_USB_COMMS_
697 armjtagew_debug_buffer(buffer
, byte_length
);
700 if (jtag_read_buffer(buffer
, command
) != ERROR_OK
)
702 armjtagew_tap_init();
703 return ERROR_JTAG_QUEUE_FAILED
;
706 if (pending_scan_result
->buffer
!= NULL
)
708 free(pending_scan_result
->buffer
);
714 LOG_ERROR("armjtagew_tap_execute, wrong result %d, expected %d", result
, byte_length
);
715 return ERROR_JTAG_QUEUE_FAILED
;
718 armjtagew_tap_init();
724 /*****************************************************************************/
725 /* JLink USB low-level functions */
727 static struct armjtagew
* armjtagew_usb_open()
729 struct usb_bus
*busses
;
731 struct usb_device
*dev
;
733 struct armjtagew
*result
;
735 result
= (struct armjtagew
*) malloc(sizeof(struct armjtagew
));
741 busses
= usb_get_busses();
743 /* find armjtagew device in usb bus */
745 for (bus
= busses
; bus
; bus
= bus
->next
)
747 for (dev
= bus
->devices
; dev
; dev
= dev
->next
)
749 if ((dev
->descriptor
.idVendor
== USB_VID
) && (dev
->descriptor
.idProduct
== USB_PID
))
751 result
->usb_handle
= usb_open(dev
);
754 /* usb_set_configuration required under win32 */
755 usb_set_configuration(result
->usb_handle
, dev
->config
[0].bConfigurationValue
);
757 usb_claim_interface(result
->usb_handle
, 0);
761 * This makes problems under Mac OS X. And is not needed
762 * under Windows. Hopefully this will not break a linux build
764 usb_set_altinterface(result
->usb_handle
, 0);
775 static void armjtagew_usb_close(struct armjtagew
*armjtagew
)
777 usb_close(armjtagew
->usb_handle
);
781 /* Send a message and receive the reply. */
782 static int armjtagew_usb_message(struct armjtagew
*armjtagew
, int out_length
, int in_length
)
786 result
= armjtagew_usb_write(armjtagew
, out_length
);
787 if (result
== out_length
)
789 result
= armjtagew_usb_read(armjtagew
, in_length
);
790 if (result
!= in_length
)
792 LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)", in_length
, result
);
798 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length
, result
);
804 /* Write data from out_buffer to USB. */
805 static int armjtagew_usb_write(struct armjtagew
*armjtagew
, int out_length
)
809 if (out_length
> ARMJTAGEW_OUT_BUFFER_SIZE
)
811 LOG_ERROR("armjtagew_write illegal out_length=%d (max=%d)", out_length
, ARMJTAGEW_OUT_BUFFER_SIZE
);
815 result
= usb_bulk_write(armjtagew
->usb_handle
, ARMJTAGEW_EPT_BULK_OUT
, \
816 (char*)usb_out_buffer
, out_length
, ARMJTAGEW_USB_TIMEOUT
);
818 DEBUG_JTAG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length
, result
);
820 #ifdef _DEBUG_USB_COMMS_
821 armjtagew_debug_buffer(usb_out_buffer
, out_length
);
826 /* Read data from USB into in_buffer. */
827 static int armjtagew_usb_read(struct armjtagew
*armjtagew
, int exp_in_length
)
829 int result
= usb_bulk_read(armjtagew
->usb_handle
, ARMJTAGEW_EPT_BULK_IN
, \
830 (char*)usb_in_buffer
, exp_in_length
, ARMJTAGEW_USB_TIMEOUT
);
832 DEBUG_JTAG_IO("armjtagew_usb_read, result = %d", result
);
834 #ifdef _DEBUG_USB_COMMS_
835 armjtagew_debug_buffer(usb_in_buffer
, result
);
841 #ifdef _DEBUG_USB_COMMS_
842 #define BYTES_PER_LINE 16
844 static void armjtagew_debug_buffer(uint8_t *buffer
, int length
)
851 for (i
= 0; i
< length
; i
+= BYTES_PER_LINE
)
853 snprintf(line
, 5, "%04x", i
);
854 for (j
= i
; j
< i
+ BYTES_PER_LINE
&& j
< length
; j
++)
856 snprintf(s
, 4, " %02x", buffer
[j
]);
859 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)