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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
23 #include <jtag/interface.h>
24 #include <jtag/commands.h>
25 #include "libusb_helper.h"
27 #define USB_VID 0x15ba
28 #define USB_PID 0x001e
30 #define ARMJTAGEW_EPT_BULK_OUT 0x01u
31 #define ARMJTAGEW_EPT_BULK_IN 0x82u
33 #define ARMJTAGEW_USB_TIMEOUT 2000
35 #define ARMJTAGEW_IN_BUFFER_SIZE (4*1024)
36 #define ARMJTAGEW_OUT_BUFFER_SIZE (4*1024)
38 /* USB command request codes. */
39 #define CMD_GET_VERSION 0x00
40 #define CMD_SELECT_DPIMPL 0x10
41 #define CMD_SET_TCK_FREQUENCY 0x11
42 #define CMD_GET_TCK_FREQUENCY 0x12
43 #define CMD_MEASURE_MAX_TCK_FREQ 0x15
44 #define CMD_MEASURE_RTCK_RESPONSE 0x16
45 #define CMD_TAP_SHIFT 0x17
46 #define CMD_SET_TAPHW_STATE 0x20
47 #define CMD_GET_TAPHW_STATE 0x21
48 #define CMD_TGPWR_SETUP 0x22
50 /* Global USB buffers */
51 static uint8_t usb_in_buffer
[ARMJTAGEW_IN_BUFFER_SIZE
];
52 static uint8_t usb_out_buffer
[ARMJTAGEW_OUT_BUFFER_SIZE
];
54 /* Queue command functions */
55 static void armjtagew_end_state(tap_state_t state
);
56 static void armjtagew_state_move(void);
57 static void armjtagew_path_move(int num_states
, tap_state_t
*path
);
58 static void armjtagew_runtest(int num_cycles
);
59 static void armjtagew_scan(bool ir_scan
,
63 struct scan_command
*command
);
64 static void armjtagew_reset(int trst
, int srst
);
65 /* static void armjtagew_simple_command(uint8_t command); */
66 static int armjtagew_get_status(void);
68 /* tap buffer functions */
69 static void armjtagew_tap_init(void);
70 static int armjtagew_tap_execute(void);
71 static void armjtagew_tap_ensure_space(int scans
, int bits
);
72 static void armjtagew_tap_append_step(int tms
, int tdi
);
73 static void armjtagew_tap_append_scan(int length
, uint8_t *buffer
, struct scan_command
*command
);
75 /* ARM-JTAG-EW lowlevel functions */
77 struct libusb_device_handle
*usb_handle
;
80 static struct armjtagew
*armjtagew_usb_open(void);
81 static void armjtagew_usb_close(struct armjtagew
*armjtagew
);
82 static int armjtagew_usb_message(struct armjtagew
*armjtagew
, int out_length
, int in_length
);
83 static int armjtagew_usb_write(struct armjtagew
*armjtagew
, int out_length
);
84 static int armjtagew_usb_read(struct armjtagew
*armjtagew
, int exp_in_length
);
86 /* helper functions */
87 static int armjtagew_get_version_info(void);
89 #ifdef _DEBUG_USB_COMMS_
90 static void armjtagew_debug_buffer(uint8_t *buffer
, int length
);
93 static struct armjtagew
*armjtagew_handle
;
95 /**************************************************************************
96 * External interface implementation */
98 static int armjtagew_execute_queue(void)
100 struct jtag_command
*cmd
= jtag_command_queue
;
105 while (cmd
!= NULL
) {
108 LOG_DEBUG_IO("runtest %i cycles, end in %i",
109 cmd
->cmd
.runtest
->num_cycles
,
110 cmd
->cmd
.runtest
->end_state
);
112 armjtagew_end_state(cmd
->cmd
.runtest
->end_state
);
113 armjtagew_runtest(cmd
->cmd
.runtest
->num_cycles
);
117 LOG_DEBUG_IO("statemove end in %i", cmd
->cmd
.statemove
->end_state
);
119 armjtagew_end_state(cmd
->cmd
.statemove
->end_state
);
120 armjtagew_state_move();
124 LOG_DEBUG_IO("pathmove: %i states, end in %i",
125 cmd
->cmd
.pathmove
->num_states
,
126 cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]);
128 armjtagew_path_move(cmd
->cmd
.pathmove
->num_states
,
129 cmd
->cmd
.pathmove
->path
);
133 LOG_DEBUG_IO("scan end in %i", cmd
->cmd
.scan
->end_state
);
135 armjtagew_end_state(cmd
->cmd
.scan
->end_state
);
137 scan_size
= jtag_build_buffer(cmd
->cmd
.scan
, &buffer
);
138 LOG_DEBUG_IO("scan input, length = %d", scan_size
);
140 #ifdef _DEBUG_USB_COMMS_
141 armjtagew_debug_buffer(buffer
, (scan_size
+ 7) / 8);
143 type
= jtag_scan_type(cmd
->cmd
.scan
);
144 armjtagew_scan(cmd
->cmd
.scan
->ir_scan
,
146 scan_size
, cmd
->cmd
.scan
);
150 LOG_DEBUG_IO("reset trst: %i srst %i",
151 cmd
->cmd
.reset
->trst
,
152 cmd
->cmd
.reset
->srst
);
154 armjtagew_tap_execute();
156 if (cmd
->cmd
.reset
->trst
== 1)
157 tap_set_state(TAP_RESET
);
158 armjtagew_reset(cmd
->cmd
.reset
->trst
, cmd
->cmd
.reset
->srst
);
162 LOG_DEBUG_IO("sleep %" PRIu32
, cmd
->cmd
.sleep
->us
);
163 armjtagew_tap_execute();
164 jtag_sleep(cmd
->cmd
.sleep
->us
);
168 LOG_ERROR("BUG: unknown JTAG command type encountered");
174 return armjtagew_tap_execute();
177 /* Sets speed in kHz. */
178 static int armjtagew_speed(int speed
)
184 usb_out_buffer
[0] = CMD_SET_TCK_FREQUENCY
;
185 buf_set_u32(usb_out_buffer
+ 1, 0, 32, speed
*1000);
187 result
= armjtagew_usb_message(armjtagew_handle
, 5, 4);
190 LOG_ERROR("ARM-JTAG-EW setting speed failed (%d)", result
);
191 return ERROR_JTAG_DEVICE_ERROR
;
194 usb_out_buffer
[0] = CMD_GET_TCK_FREQUENCY
;
195 result
= armjtagew_usb_message(armjtagew_handle
, 1, 4);
196 speed_real
= (int)buf_get_u32(usb_in_buffer
, 0, 32) / 1000;
198 LOG_ERROR("ARM-JTAG-EW getting speed failed (%d)", result
);
199 return ERROR_JTAG_DEVICE_ERROR
;
201 LOG_INFO("Requested speed %dkHz, emulator reported %dkHz.", speed
, speed_real
);
206 static int armjtagew_khz(int khz
, int *jtag_speed
)
213 static int armjtagew_speed_div(int speed
, int *khz
)
220 static int armjtagew_init(void)
224 armjtagew_handle
= armjtagew_usb_open();
226 if (armjtagew_handle
== 0) {
228 "Cannot find ARM-JTAG-EW Interface! Please check connection and permissions.");
229 return ERROR_JTAG_INIT_FAILED
;
233 while (check_cnt
< 3) {
234 if (armjtagew_get_version_info() == ERROR_OK
) {
235 /* attempt to get status */
236 armjtagew_get_status();
244 LOG_INFO("ARM-JTAG-EW initial read failed, don't worry");
246 /* Initial JTAG speed (for reset and initialization): 32 kHz */
249 LOG_INFO("ARM-JTAG-EW JTAG Interface ready");
251 armjtagew_reset(0, 0);
252 armjtagew_tap_init();
257 static int armjtagew_quit(void)
259 armjtagew_usb_close(armjtagew_handle
);
263 /**************************************************************************
264 * Queue command implementations */
266 static void armjtagew_end_state(tap_state_t state
)
268 if (tap_is_state_stable(state
))
269 tap_set_end_state(state
);
271 LOG_ERROR("BUG: %i is not a valid end state", state
);
276 /* Goes to the end state. */
277 static void armjtagew_state_move(void)
281 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(), tap_get_end_state());
282 int tms_count
= tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
284 for (i
= 0; i
< tms_count
; i
++) {
285 tms
= (tms_scan
>> i
) & 1;
286 armjtagew_tap_append_step(tms
, 0);
289 tap_set_state(tap_get_end_state());
292 static void armjtagew_path_move(int num_states
, tap_state_t
*path
)
296 for (i
= 0; i
< num_states
; i
++) {
298 * TODO: The ARM-JTAG-EW hardware delays TDI with 3 TCK cycles when in RTCK mode.
299 * Either handle that here, or update the documentation with examples
300 * how to fix that in the configuration files.
302 if (path
[i
] == tap_state_transition(tap_get_state(), false))
303 armjtagew_tap_append_step(0, 0);
304 else if (path
[i
] == tap_state_transition(tap_get_state(), true))
305 armjtagew_tap_append_step(1, 0);
307 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
308 tap_state_name(tap_get_state()), tap_state_name(path
[i
]));
312 tap_set_state(path
[i
]);
315 tap_set_end_state(tap_get_state());
318 static void armjtagew_runtest(int num_cycles
)
322 tap_state_t saved_end_state
= tap_get_end_state();
324 /* only do a state_move when we're not already in IDLE */
325 if (tap_get_state() != TAP_IDLE
) {
326 armjtagew_end_state(TAP_IDLE
);
327 armjtagew_state_move();
330 /* execute num_cycles */
331 for (i
= 0; i
< num_cycles
; i
++)
332 armjtagew_tap_append_step(0, 0);
334 /* finish in end_state */
335 armjtagew_end_state(saved_end_state
);
336 if (tap_get_state() != tap_get_end_state())
337 armjtagew_state_move();
340 static void armjtagew_scan(bool ir_scan
,
344 struct scan_command
*command
)
346 tap_state_t saved_end_state
;
348 armjtagew_tap_ensure_space(1, scan_size
+ 8);
350 saved_end_state
= tap_get_end_state();
352 /* Move to appropriate scan state */
353 armjtagew_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
355 /* Only move if we're not already there */
356 if (tap_get_state() != tap_get_end_state())
357 armjtagew_state_move();
359 armjtagew_end_state(saved_end_state
);
362 armjtagew_tap_append_scan(scan_size
, buffer
, command
);
364 /* We are in Exit1, go to Pause */
365 armjtagew_tap_append_step(0, 0);
367 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
369 if (tap_get_state() != tap_get_end_state())
370 armjtagew_state_move();
373 static void armjtagew_reset(int trst
, int srst
)
375 const uint8_t trst_mask
= (1u << 5);
376 const uint8_t srst_mask
= (1u << 6);
379 uint8_t change_mask
= 0;
382 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
386 outp_en
&= ~srst_mask
; /* tristate */
387 change_mask
|= srst_mask
;
388 } else if (srst
== 1) {
390 outp_en
|= srst_mask
;
391 change_mask
|= srst_mask
;
396 outp_en
&= ~trst_mask
; /* tristate */
397 change_mask
|= trst_mask
;
398 } else if (trst
== 1) {
400 outp_en
|= trst_mask
;
401 change_mask
|= trst_mask
;
404 usb_out_buffer
[0] = CMD_SET_TAPHW_STATE
;
405 usb_out_buffer
[1] = val
;
406 usb_out_buffer
[2] = outp_en
;
407 usb_out_buffer
[3] = change_mask
;
408 result
= armjtagew_usb_write(armjtagew_handle
, 4);
410 LOG_ERROR("ARM-JTAG-EW TRST/SRST pin set failed failed (%d)", result
);
413 static int armjtagew_get_status(void)
417 usb_out_buffer
[0] = CMD_GET_TAPHW_STATE
;
418 result
= armjtagew_usb_message(armjtagew_handle
, 1, 12);
421 unsigned int u_tg
= buf_get_u32(usb_in_buffer
, 0, 16);
423 "U_tg = %d mV, U_aux = %d mV, U_tgpwr = %d mV, I_tgpwr = %d mA, D1 = %d, Target power %s %s",
424 (int)(buf_get_u32(usb_in_buffer
+ 0, 0, 16)),
425 (int)(buf_get_u32(usb_in_buffer
+ 2, 0, 16)),
426 (int)(buf_get_u32(usb_in_buffer
+ 4, 0, 16)),
427 (int)(buf_get_u32(usb_in_buffer
+ 6, 0, 16)),
429 usb_in_buffer
[11] ? "OVERCURRENT" : "OK",
430 usb_in_buffer
[10] ? "enabled" : "disabled");
433 LOG_ERROR("Vref too low. Check Target Power");
435 LOG_ERROR("ARM-JTAG-EW command CMD_GET_TAPHW_STATE failed (%d)", result
);
440 static int armjtagew_get_version_info(void)
446 /* query hardware version */
447 usb_out_buffer
[0] = CMD_GET_VERSION
;
448 result
= armjtagew_usb_message(armjtagew_handle
, 1, 4 + 15 + 256);
451 LOG_ERROR("ARM-JTAG-EW command CMD_GET_VERSION failed (%d)", result
);
452 return ERROR_JTAG_DEVICE_ERROR
;
455 memcpy(sn
, usb_in_buffer
+ 4, 15);
457 memcpy(auxinfo
, usb_in_buffer
+ 4+15, 256);
461 "ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s",
464 isgraph(usb_in_buffer
[2]) ? usb_in_buffer
[2] : 'X',
468 if (1 != usb_in_buffer
[1] || 6 != usb_in_buffer
[0])
470 "ARM-JTAG-EW firmware version %d.%d is untested with this version of OpenOCD. You might experience unexpected behavior.",
476 COMMAND_HANDLER(armjtagew_handle_armjtagew_info_command
)
478 if (armjtagew_get_version_info() == ERROR_OK
) {
479 /* attempt to get status */
480 armjtagew_get_status();
486 static const struct command_registration armjtagew_command_handlers
[] = {
488 .name
= "armjtagew_info",
489 .handler
= &armjtagew_handle_armjtagew_info_command
,
490 .mode
= COMMAND_EXEC
,
491 .help
= "query armjtagew info",
494 COMMAND_REGISTRATION_DONE
497 static struct jtag_interface armjtagew_interface
= {
498 .execute_queue
= armjtagew_execute_queue
,
501 struct adapter_driver armjtagew_adapter_driver
= {
502 .name
= "arm-jtag-ew",
503 .transports
= jtag_only
,
504 .commands
= armjtagew_command_handlers
,
506 .init
= armjtagew_init
,
507 .quit
= armjtagew_quit
,
508 .speed
= armjtagew_speed
,
509 .khz
= armjtagew_khz
,
510 .speed_div
= armjtagew_speed_div
,
512 .jtag_ops
= &armjtagew_interface
,
515 /**************************************************************************
516 * ARM-JTAG-EW tap functions */
518 /* 2048 is the max value we can use here */
519 #define ARMJTAGEW_TAP_BUFFER_SIZE 2048
521 static int tap_length
;
522 static uint8_t tms_buffer
[ARMJTAGEW_TAP_BUFFER_SIZE
];
523 static uint8_t tdi_buffer
[ARMJTAGEW_TAP_BUFFER_SIZE
];
524 static uint8_t tdo_buffer
[ARMJTAGEW_TAP_BUFFER_SIZE
];
526 struct pending_scan_result
{
527 int first
; /* First bit position in tdo_buffer to read */
528 int length
; /* Number of bits to read */
529 struct scan_command
*command
; /* Corresponding scan command */
533 #define MAX_PENDING_SCAN_RESULTS 256
535 static int pending_scan_results_length
;
536 static struct pending_scan_result pending_scan_results_buffer
[MAX_PENDING_SCAN_RESULTS
];
540 static void armjtagew_tap_init(void)
543 pending_scan_results_length
= 0;
546 static void armjtagew_tap_ensure_space(int scans
, int bits
)
548 int available_scans
= MAX_PENDING_SCAN_RESULTS
- pending_scan_results_length
;
549 int available_bits
= ARMJTAGEW_TAP_BUFFER_SIZE
* 8 - tap_length
;
551 if (scans
> available_scans
|| bits
> available_bits
)
552 armjtagew_tap_execute();
555 static void armjtagew_tap_append_step(int tms
, int tdi
)
558 int index_local
= tap_length
/ 8;
560 if (index_local
< ARMJTAGEW_TAP_BUFFER_SIZE
) {
561 int bit_index
= tap_length
% 8;
562 uint8_t bit
= 1 << bit_index
;
565 tms_buffer
[index_local
] |= bit
;
567 tms_buffer
[index_local
] &= ~bit
;
570 tdi_buffer
[index_local
] |= bit
;
572 tdi_buffer
[index_local
] &= ~bit
;
576 LOG_ERROR("armjtagew_tap_append_step, overflow");
579 void armjtagew_tap_append_scan(int length
, uint8_t *buffer
, struct scan_command
*command
)
581 struct pending_scan_result
*pending_scan_result
=
582 &pending_scan_results_buffer
[pending_scan_results_length
];
585 pending_scan_result
->first
= tap_length
;
586 pending_scan_result
->length
= length
;
587 pending_scan_result
->command
= command
;
588 pending_scan_result
->buffer
= buffer
;
590 for (i
= 0; i
< length
; i
++)
591 armjtagew_tap_append_step((i
< length
-1 ? 0 : 1), (buffer
[i
/8] >> (i
%8)) & 1);
592 pending_scan_results_length
++;
595 /* Pad and send a tap sequence to the device, and receive the answer.
596 * For the purpose of padding we assume that we are in idle or pause state. */
597 static int armjtagew_tap_execute(void)
605 if (tap_length
> 0) {
606 /* Pad last byte so that tap_length is divisible by 8 */
607 while (tap_length
% 8 != 0) {
608 /* More of the last TMS value keeps us in the same state,
609 * analogous to free-running JTAG interfaces. */
610 armjtagew_tap_append_step(last_tms
, 0);
613 byte_length
= tap_length
/ 8;
615 usb_out_buffer
[0] = CMD_TAP_SHIFT
;
616 buf_set_u32(usb_out_buffer
+ 1, 0, 16, byte_length
);
619 for (i
= 0; i
< byte_length
; i
++)
620 usb_out_buffer
[tms_offset
+ i
] = flip_u32(tms_buffer
[i
], 8);
622 tdi_offset
= tms_offset
+ byte_length
;
623 for (i
= 0; i
< byte_length
; i
++)
624 usb_out_buffer
[tdi_offset
+ i
] = flip_u32(tdi_buffer
[i
], 8);
626 result
= armjtagew_usb_message(armjtagew_handle
,
633 stat_local
= (int)buf_get_u32(usb_in_buffer
+ byte_length
, 0, 32);
636 "armjtagew_tap_execute, emulator returned error code %d for a CMD_TAP_SHIFT command",
638 return ERROR_JTAG_QUEUE_FAILED
;
641 for (i
= 0; i
< byte_length
; i
++)
642 tdo_buffer
[i
] = flip_u32(usb_in_buffer
[i
], 8);
644 for (i
= 0; i
< pending_scan_results_length
; i
++) {
645 struct pending_scan_result
*pending_scan_result
=
646 &pending_scan_results_buffer
[i
];
647 uint8_t *buffer
= pending_scan_result
->buffer
;
648 int length
= pending_scan_result
->length
;
649 int first
= pending_scan_result
->first
;
650 struct scan_command
*command
= pending_scan_result
->command
;
653 buf_set_buf(tdo_buffer
, first
, buffer
, 0, length
);
655 LOG_DEBUG_IO("pending scan result, length = %d", length
);
657 #ifdef _DEBUG_USB_COMMS_
658 armjtagew_debug_buffer(buffer
, byte_length
);
661 if (jtag_read_buffer(buffer
, command
) != ERROR_OK
) {
662 armjtagew_tap_init();
663 return ERROR_JTAG_QUEUE_FAILED
;
666 free(pending_scan_result
->buffer
);
669 LOG_ERROR("armjtagew_tap_execute, wrong result %d, expected %d",
672 return ERROR_JTAG_QUEUE_FAILED
;
675 armjtagew_tap_init();
681 /****************************************************************************
682 * JLink USB low-level functions */
684 static struct armjtagew
*armjtagew_usb_open(void)
686 const uint16_t vids
[] = { USB_VID
, 0 };
687 const uint16_t pids
[] = { USB_PID
, 0 };
688 struct libusb_device_handle
*dev
;
690 if (jtag_libusb_open(vids
, pids
, NULL
, &dev
, NULL
) != ERROR_OK
)
693 struct armjtagew
*result
= malloc(sizeof(struct armjtagew
));
694 result
->usb_handle
= dev
;
697 /* libusb_set_configuration required under win32 */
698 struct libusb_config_descriptor
*config
;
699 struct libusb_device
*usb_dev
= libusb_get_device(dev
);
700 libusb_get_config_descriptor(usb_dev
, 0, &config
);
701 libusb_set_configuration(dev
, config
->bConfigurationValue
);
703 libusb_claim_interface(dev
, 0);
706 * This makes problems under Mac OS X. And is not needed
707 * under Windows. Hopefully this will not break a linux build
709 libusb_set_interface_alt_setting(dev
, 0, 0);
714 static void armjtagew_usb_close(struct armjtagew
*armjtagew
)
716 libusb_close(armjtagew
->usb_handle
);
720 /* Send a message and receive the reply. */
721 static int armjtagew_usb_message(struct armjtagew
*armjtagew
, int out_length
, int in_length
)
725 result
= armjtagew_usb_write(armjtagew
, out_length
);
726 if (result
== out_length
) {
727 result
= armjtagew_usb_read(armjtagew
, in_length
);
728 if (result
!= in_length
) {
729 LOG_ERROR("jtag_libusb_bulk_read failed (requested=%d, result=%d)",
735 LOG_ERROR("jtag_libusb_bulk_write failed (requested=%d, result=%d)", out_length
, result
);
741 /* Write data from out_buffer to USB. */
742 static int armjtagew_usb_write(struct armjtagew
*armjtagew
, int out_length
)
747 if (out_length
> ARMJTAGEW_OUT_BUFFER_SIZE
) {
748 LOG_ERROR("armjtagew_write illegal out_length=%d (max=%d)",
750 ARMJTAGEW_OUT_BUFFER_SIZE
);
754 result
= jtag_libusb_bulk_write(armjtagew
->usb_handle
, ARMJTAGEW_EPT_BULK_OUT
,
755 (char *)usb_out_buffer
, out_length
, ARMJTAGEW_USB_TIMEOUT
, &transferred
);
757 LOG_DEBUG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length
, result
);
759 #ifdef _DEBUG_USB_COMMS_
760 armjtagew_debug_buffer(usb_out_buffer
, out_length
);
762 if (result
!= ERROR_OK
)
767 /* Read data from USB into in_buffer. */
768 static int armjtagew_usb_read(struct armjtagew
*armjtagew
, int exp_in_length
)
771 int result
= jtag_libusb_bulk_read(armjtagew
->usb_handle
, ARMJTAGEW_EPT_BULK_IN
,
772 (char *)usb_in_buffer
, exp_in_length
, ARMJTAGEW_USB_TIMEOUT
, &transferred
);
774 LOG_DEBUG_IO("armjtagew_usb_read, result = %d", result
);
776 #ifdef _DEBUG_USB_COMMS_
777 armjtagew_debug_buffer(usb_in_buffer
, result
);
779 if (result
!= ERROR_OK
)
784 #ifdef _DEBUG_USB_COMMS_
785 #define BYTES_PER_LINE 16
787 static void armjtagew_debug_buffer(uint8_t *buffer
, int length
)
794 for (i
= 0; i
< length
; i
+= BYTES_PER_LINE
) {
795 snprintf(line
, 5, "%04x", i
);
796 for (j
= i
; j
< i
+ BYTES_PER_LINE
&& j
< length
; j
++) {
797 snprintf(s
, 4, " %02x", buffer
[j
]);
800 LOG_DEBUG("%s", line
);
802 /* Prevent GDB timeout (writing to log might take some time) */
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)