jtag: only change state if necessary
[openocd.git] / src / jtag / drivers / arm-jtag-ew.c
1 /***************************************************************************
2 * Copyright (C) 2009 by Dimitar Dimitrov <dinuxbg@gmail.com> *
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 <jtag/interface.h>
26 #include <jtag/commands.h>
27 #include <usb.h>
28 #include "usb_common.h"
29
30 #define USB_VID 0x15ba
31 #define USB_PID 0x001e
32
33 #define ARMJTAGEW_EPT_BULK_OUT 0x01u
34 #define ARMJTAGEW_EPT_BULK_IN 0x82u
35
36 #define ARMJTAGEW_USB_TIMEOUT 2000
37
38 #define ARMJTAGEW_IN_BUFFER_SIZE (4*1024)
39 #define ARMJTAGEW_OUT_BUFFER_SIZE (4*1024)
40
41 /* USB command request codes. */
42 #define CMD_GET_VERSION 0x00
43 #define CMD_SELECT_DPIMPL 0x10
44 #define CMD_SET_TCK_FREQUENCY 0x11
45 #define CMD_GET_TCK_FREQUENCY 0x12
46 #define CMD_MEASURE_MAX_TCK_FREQ 0x15
47 #define CMD_MEASURE_RTCK_RESPONSE 0x16
48 #define CMD_TAP_SHIFT 0x17
49 #define CMD_SET_TAPHW_STATE 0x20
50 #define CMD_GET_TAPHW_STATE 0x21
51 #define CMD_TGPWR_SETUP 0x22
52
53 /* Global USB buffers */
54 static uint8_t usb_in_buffer[ARMJTAGEW_IN_BUFFER_SIZE];
55 static uint8_t usb_out_buffer[ARMJTAGEW_OUT_BUFFER_SIZE];
56
57 /* Queue command functions */
58 static void armjtagew_end_state(tap_state_t state);
59 static void armjtagew_state_move(void);
60 static void armjtagew_path_move(int num_states, tap_state_t *path);
61 static void armjtagew_runtest(int num_cycles);
62 static void armjtagew_scan(bool ir_scan,
63 enum scan_type type,
64 uint8_t *buffer,
65 int scan_size,
66 struct scan_command *command);
67 static void armjtagew_reset(int trst, int srst);
68 /* static void armjtagew_simple_command(uint8_t command); */
69 static int armjtagew_get_status(void);
70
71 /* tap buffer functions */
72 static void armjtagew_tap_init(void);
73 static int armjtagew_tap_execute(void);
74 static void armjtagew_tap_ensure_space(int scans, int bits);
75 static void armjtagew_tap_append_step(int tms, int tdi);
76 static void armjtagew_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command);
77
78 /* ARM-JTAG-EW lowlevel functions */
79 struct armjtagew {
80 struct usb_dev_handle *usb_handle;
81 };
82
83 static struct armjtagew *armjtagew_usb_open(void);
84 static void armjtagew_usb_close(struct armjtagew *armjtagew);
85 static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length);
86 static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length);
87 static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length);
88
89 /* helper functions */
90 static int armjtagew_get_version_info(void);
91
92 #ifdef _DEBUG_USB_COMMS_
93 static void armjtagew_debug_buffer(uint8_t *buffer, int length);
94 #endif
95
96 static struct armjtagew *armjtagew_handle;
97
98 /**************************************************************************
99 * External interface implementation */
100
101 static int armjtagew_execute_queue(void)
102 {
103 struct jtag_command *cmd = jtag_command_queue;
104 int scan_size;
105 enum scan_type type;
106 uint8_t *buffer;
107
108 while (cmd != NULL) {
109 switch (cmd->type) {
110 case JTAG_RUNTEST:
111 DEBUG_JTAG_IO("runtest %i cycles, end in %i",
112 cmd->cmd.runtest->num_cycles, \
113 cmd->cmd.runtest->end_state);
114
115 armjtagew_end_state(cmd->cmd.runtest->end_state);
116 armjtagew_runtest(cmd->cmd.runtest->num_cycles);
117 break;
118
119 case JTAG_TLR_RESET:
120 DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
121
122 armjtagew_end_state(cmd->cmd.statemove->end_state);
123 armjtagew_state_move();
124 break;
125
126 case JTAG_PATHMOVE:
127 DEBUG_JTAG_IO("pathmove: %i states, end in %i", \
128 cmd->cmd.pathmove->num_states, \
129 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
130
131 armjtagew_path_move(cmd->cmd.pathmove->num_states,
132 cmd->cmd.pathmove->path);
133 break;
134
135 case JTAG_SCAN:
136 DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state);
137
138 armjtagew_end_state(cmd->cmd.scan->end_state);
139
140 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
141 DEBUG_JTAG_IO("scan input, length = %d", scan_size);
142
143 #ifdef _DEBUG_USB_COMMS_
144 armjtagew_debug_buffer(buffer, (scan_size + 7) / 8);
145 #endif
146 type = jtag_scan_type(cmd->cmd.scan);
147 armjtagew_scan(cmd->cmd.scan->ir_scan,
148 type, buffer,
149 scan_size, cmd->cmd.scan);
150 break;
151
152 case JTAG_RESET:
153 DEBUG_JTAG_IO("reset trst: %i srst %i",
154 cmd->cmd.reset->trst,
155 cmd->cmd.reset->srst);
156
157 armjtagew_tap_execute();
158
159 if (cmd->cmd.reset->trst == 1)
160 tap_set_state(TAP_RESET);
161 armjtagew_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
162 break;
163
164 case JTAG_SLEEP:
165 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
166 armjtagew_tap_execute();
167 jtag_sleep(cmd->cmd.sleep->us);
168 break;
169
170 default:
171 LOG_ERROR("BUG: unknown JTAG command type encountered");
172 exit(-1);
173 }
174 cmd = cmd->next;
175 }
176
177 return armjtagew_tap_execute();
178 }
179
180 /* Sets speed in kHz. */
181 static int armjtagew_speed(int speed)
182 {
183 int result;
184 int speed_real;
185
186
187 usb_out_buffer[0] = CMD_SET_TCK_FREQUENCY;
188 buf_set_u32(usb_out_buffer + 1, 0, 32, speed*1000);
189
190 result = armjtagew_usb_message(armjtagew_handle, 5, 4);
191
192 if (result < 0) {
193 LOG_ERROR("ARM-JTAG-EW setting speed failed (%d)", result);
194 return ERROR_JTAG_DEVICE_ERROR;
195 }
196
197 usb_out_buffer[0] = CMD_GET_TCK_FREQUENCY;
198 result = armjtagew_usb_message(armjtagew_handle, 1, 4);
199 speed_real = (int)buf_get_u32(usb_in_buffer, 0, 32) / 1000;
200 if (result < 0) {
201 LOG_ERROR("ARM-JTAG-EW getting speed failed (%d)", result);
202 return ERROR_JTAG_DEVICE_ERROR;
203 } else
204 LOG_INFO("Requested speed %dkHz, emulator reported %dkHz.", speed, speed_real);
205
206 return ERROR_OK;
207 }
208
209 static int armjtagew_khz(int khz, int *jtag_speed)
210 {
211 *jtag_speed = khz;
212
213 return ERROR_OK;
214 }
215
216 static int armjtagew_speed_div(int speed, int *khz)
217 {
218 *khz = speed;
219
220 return ERROR_OK;
221 }
222
223 static int armjtagew_init(void)
224 {
225 int check_cnt;
226
227 armjtagew_handle = armjtagew_usb_open();
228
229 if (armjtagew_handle == 0) {
230 LOG_ERROR(
231 "Cannot find ARM-JTAG-EW Interface! Please check connection and permissions.");
232 return ERROR_JTAG_INIT_FAILED;
233 }
234
235 check_cnt = 0;
236 while (check_cnt < 3) {
237 if (armjtagew_get_version_info() == ERROR_OK) {
238 /* attempt to get status */
239 armjtagew_get_status();
240 break;
241 }
242
243 check_cnt++;
244 }
245
246 if (check_cnt == 3)
247 LOG_INFO("ARM-JTAG-EW initial read failed, don't worry");
248
249 /* Initial JTAG speed (for reset and initialization): 32 kHz */
250 armjtagew_speed(32);
251
252 LOG_INFO("ARM-JTAG-EW JTAG Interface ready");
253
254 armjtagew_reset(0, 0);
255 armjtagew_tap_init();
256
257 return ERROR_OK;
258 }
259
260 static int armjtagew_quit(void)
261 {
262 armjtagew_usb_close(armjtagew_handle);
263 return ERROR_OK;
264 }
265
266 /**************************************************************************
267 * Queue command implementations */
268
269 static void armjtagew_end_state(tap_state_t state)
270 {
271 if (tap_is_state_stable(state))
272 tap_set_end_state(state);
273 else {
274 LOG_ERROR("BUG: %i is not a valid end state", state);
275 exit(-1);
276 }
277 }
278
279 /* Goes to the end state. */
280 static void armjtagew_state_move(void)
281 {
282 int i;
283 int tms = 0;
284 uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
285 int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
286
287 for (i = 0; i < tms_count; i++) {
288 tms = (tms_scan >> i) & 1;
289 armjtagew_tap_append_step(tms, 0);
290 }
291
292 tap_set_state(tap_get_end_state());
293 }
294
295 static void armjtagew_path_move(int num_states, tap_state_t *path)
296 {
297 int i;
298
299 for (i = 0; i < num_states; i++) {
300 /*
301 * TODO: The ARM-JTAG-EW hardware delays TDI with 3 TCK cycles when in RTCK mode.
302 * Either handle that here, or update the documentation with examples
303 * how to fix that in the configuration files.
304 */
305 if (path[i] == tap_state_transition(tap_get_state(), false))
306 armjtagew_tap_append_step(0, 0);
307 else if (path[i] == tap_state_transition(tap_get_state(), true))
308 armjtagew_tap_append_step(1, 0);
309 else {
310 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
311 tap_state_name(tap_get_state()), tap_state_name(path[i]));
312 exit(-1);
313 }
314
315 tap_set_state(path[i]);
316 }
317
318 tap_set_end_state(tap_get_state());
319 }
320
321 static void armjtagew_runtest(int num_cycles)
322 {
323 int i;
324
325 tap_state_t saved_end_state = tap_get_end_state();
326
327 /* only do a state_move when we're not already in IDLE */
328 if (tap_get_state() != TAP_IDLE) {
329 armjtagew_end_state(TAP_IDLE);
330 armjtagew_state_move();
331 }
332
333 /* execute num_cycles */
334 for (i = 0; i < num_cycles; i++)
335 armjtagew_tap_append_step(0, 0);
336
337 /* finish in end_state */
338 armjtagew_end_state(saved_end_state);
339 if (tap_get_state() != tap_get_end_state())
340 armjtagew_state_move();
341 }
342
343 static void armjtagew_scan(bool ir_scan,
344 enum scan_type type,
345 uint8_t *buffer,
346 int scan_size,
347 struct scan_command *command)
348 {
349 tap_state_t saved_end_state;
350
351 armjtagew_tap_ensure_space(1, scan_size + 8);
352
353 saved_end_state = tap_get_end_state();
354
355 /* Move to appropriate scan state */
356 armjtagew_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
357
358 /* Only move if we're not already there */
359 if (tap_get_state() != tap_get_end_state())
360 armjtagew_state_move();
361
362 armjtagew_end_state(saved_end_state);
363
364 /* Scan */
365 armjtagew_tap_append_scan(scan_size, buffer, command);
366
367 /* We are in Exit1, go to Pause */
368 armjtagew_tap_append_step(0, 0);
369
370 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
371
372 if (tap_get_state() != tap_get_end_state())
373 armjtagew_state_move();
374 }
375
376 static void armjtagew_reset(int trst, int srst)
377 {
378 const uint8_t trst_mask = (1u << 5);
379 const uint8_t srst_mask = (1u << 6);
380 uint8_t val = 0;
381 uint8_t outp_en = 0;
382 uint8_t change_mask = 0;
383 int result;
384
385 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
386
387 if (srst == 0) {
388 val |= srst_mask;
389 outp_en &= ~srst_mask; /* tristate */
390 change_mask |= srst_mask;
391 } else if (srst == 1) {
392 val &= ~srst_mask;
393 outp_en |= srst_mask;
394 change_mask |= srst_mask;
395 }
396
397 if (trst == 0) {
398 val |= trst_mask;
399 outp_en &= ~trst_mask; /* tristate */
400 change_mask |= trst_mask;
401 } else if (trst == 1) {
402 val &= ~trst_mask;
403 outp_en |= trst_mask;
404 change_mask |= trst_mask;
405 }
406
407 usb_out_buffer[0] = CMD_SET_TAPHW_STATE;
408 usb_out_buffer[1] = val;
409 usb_out_buffer[2] = outp_en;
410 usb_out_buffer[3] = change_mask;
411 result = armjtagew_usb_write(armjtagew_handle, 4);
412 if (result != 4)
413 LOG_ERROR("ARM-JTAG-EW TRST/SRST pin set failed failed (%d)", result);
414 }
415
416 static int armjtagew_get_status(void)
417 {
418 int result;
419
420 usb_out_buffer[0] = CMD_GET_TAPHW_STATE;
421 result = armjtagew_usb_message(armjtagew_handle, 1, 12);
422
423 if (result == 0) {
424 unsigned int u_tg = buf_get_u32(usb_in_buffer, 0, 16);
425 LOG_INFO(
426 "U_tg = %d mV, U_aux = %d mV, U_tgpwr = %d mV, I_tgpwr = %d mA, D1 = %d, Target power %s %s",
427 (int)(buf_get_u32(usb_in_buffer + 0, 0, 16)),
428 (int)(buf_get_u32(usb_in_buffer + 2, 0, 16)),
429 (int)(buf_get_u32(usb_in_buffer + 4, 0, 16)),
430 (int)(buf_get_u32(usb_in_buffer + 6, 0, 16)),
431 usb_in_buffer[9],
432 usb_in_buffer[11] ? "OVERCURRENT" : "OK",
433 usb_in_buffer[10] ? "enabled" : "disabled");
434
435 if (u_tg < 1500)
436 LOG_ERROR("Vref too low. Check Target Power");
437 } else
438 LOG_ERROR("ARM-JTAG-EW command CMD_GET_TAPHW_STATE failed (%d)", result);
439
440 return ERROR_OK;
441 }
442
443 static int armjtagew_get_version_info(void)
444 {
445 int result;
446 char sn[16];
447 char auxinfo[257];
448
449 /* query hardware version */
450 usb_out_buffer[0] = CMD_GET_VERSION;
451 result = armjtagew_usb_message(armjtagew_handle, 1, 4 + 15 + 256);
452
453 if (result != 0) {
454 LOG_ERROR("ARM-JTAG-EW command CMD_GET_VERSION failed (%d)", result);
455 return ERROR_JTAG_DEVICE_ERROR;
456 }
457
458 memcpy(sn, usb_in_buffer + 4, 15);
459 sn[15] = '\0';
460 memcpy(auxinfo, usb_in_buffer + 4+15, 256);
461 auxinfo[256] = '\0';
462
463 LOG_INFO(
464 "ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s", \
465 usb_in_buffer[1],
466 usb_in_buffer[0], \
467 isgraph(usb_in_buffer[2]) ? usb_in_buffer[2] : 'X', \
468 sn,
469 auxinfo);
470
471 if (1 != usb_in_buffer[1] || 6 != usb_in_buffer[0])
472 LOG_WARNING(
473 "ARM-JTAG-EW firmware version %d.%d is untested with this version of OpenOCD. You might experience unexpected behavior.",
474 usb_in_buffer[1],
475 usb_in_buffer[0]);
476 return ERROR_OK;
477 }
478
479 COMMAND_HANDLER(armjtagew_handle_armjtagew_info_command)
480 {
481 if (armjtagew_get_version_info() == ERROR_OK) {
482 /* attempt to get status */
483 armjtagew_get_status();
484 }
485
486 return ERROR_OK;
487 }
488
489 static const struct command_registration armjtagew_command_handlers[] = {
490 {
491 .name = "armjtagew_info",
492 .handler = &armjtagew_handle_armjtagew_info_command,
493 .mode = COMMAND_EXEC,
494 .help = "query armjtagew info",
495 },
496 COMMAND_REGISTRATION_DONE
497 };
498
499 struct jtag_interface armjtagew_interface = {
500 .name = "arm-jtag-ew",
501 .commands = armjtagew_command_handlers,
502 .transports = jtag_only,
503 .execute_queue = armjtagew_execute_queue,
504 .speed = armjtagew_speed,
505 .speed_div = armjtagew_speed_div,
506 .khz = armjtagew_khz,
507 .init = armjtagew_init,
508 .quit = armjtagew_quit,
509 };
510
511 /**************************************************************************
512 * ARM-JTAG-EW tap functions */
513
514 /* 2048 is the max value we can use here */
515 #define ARMJTAGEW_TAP_BUFFER_SIZE 2048
516
517 static int tap_length;
518 static uint8_t tms_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
519 static uint8_t tdi_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
520 static uint8_t tdo_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
521
522 struct pending_scan_result {
523 int first; /* First bit position in tdo_buffer to read */
524 int length; /* Number of bits to read */
525 struct scan_command *command; /* Corresponding scan command */
526 uint8_t *buffer;
527 };
528
529 #define MAX_PENDING_SCAN_RESULTS 256
530
531 static int pending_scan_results_length;
532 static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
533
534 static int last_tms;
535
536 static void armjtagew_tap_init(void)
537 {
538 tap_length = 0;
539 pending_scan_results_length = 0;
540 }
541
542 static void armjtagew_tap_ensure_space(int scans, int bits)
543 {
544 int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
545 int available_bits = ARMJTAGEW_TAP_BUFFER_SIZE * 8 - tap_length;
546
547 if (scans > available_scans || bits > available_bits)
548 armjtagew_tap_execute();
549 }
550
551 static void armjtagew_tap_append_step(int tms, int tdi)
552 {
553 last_tms = tms;
554 int index_local = tap_length / 8;
555
556 if (index_local < ARMJTAGEW_TAP_BUFFER_SIZE) {
557 int bit_index = tap_length % 8;
558 uint8_t bit = 1 << bit_index;
559
560 if (tms)
561 tms_buffer[index_local] |= bit;
562 else
563 tms_buffer[index_local] &= ~bit;
564
565 if (tdi)
566 tdi_buffer[index_local] |= bit;
567 else
568 tdi_buffer[index_local] &= ~bit;
569
570 tap_length++;
571 } else
572 LOG_ERROR("armjtagew_tap_append_step, overflow");
573 }
574
575 void armjtagew_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command)
576 {
577 struct pending_scan_result *pending_scan_result =
578 &pending_scan_results_buffer[pending_scan_results_length];
579 int i;
580
581 pending_scan_result->first = tap_length;
582 pending_scan_result->length = length;
583 pending_scan_result->command = command;
584 pending_scan_result->buffer = buffer;
585
586 for (i = 0; i < length; i++)
587 armjtagew_tap_append_step((i < length-1 ? 0 : 1), (buffer[i/8] >> (i%8)) & 1);
588 pending_scan_results_length++;
589 }
590
591 /* Pad and send a tap sequence to the device, and receive the answer.
592 * For the purpose of padding we assume that we are in idle or pause state. */
593 static int armjtagew_tap_execute(void)
594 {
595 int byte_length;
596 int tms_offset;
597 int tdi_offset;
598 int i;
599 int result;
600
601 if (tap_length > 0) {
602 /* Pad last byte so that tap_length is divisible by 8 */
603 while (tap_length % 8 != 0) {
604 /* More of the last TMS value keeps us in the same state,
605 * analogous to free-running JTAG interfaces. */
606 armjtagew_tap_append_step(last_tms, 0);
607 }
608
609 byte_length = tap_length / 8;
610
611 usb_out_buffer[0] = CMD_TAP_SHIFT;
612 buf_set_u32(usb_out_buffer + 1, 0, 16, byte_length);
613
614 tms_offset = 3;
615 for (i = 0; i < byte_length; i++)
616 usb_out_buffer[tms_offset + i] = flip_u32(tms_buffer[i], 8);
617
618 tdi_offset = tms_offset + byte_length;
619 for (i = 0; i < byte_length; i++)
620 usb_out_buffer[tdi_offset + i] = flip_u32(tdi_buffer[i], 8);
621
622 result = armjtagew_usb_message(armjtagew_handle,
623 3 + 2 * byte_length,
624 byte_length + 4);
625
626 if (result == 0) {
627 int stat_local;
628
629 stat_local = (int)buf_get_u32(usb_in_buffer + byte_length, 0, 32);
630 if (stat_local) {
631 LOG_ERROR(
632 "armjtagew_tap_execute, emulator returned error code %d for a CMD_TAP_SHIFT command",
633 stat_local);
634 return ERROR_JTAG_QUEUE_FAILED;
635 }
636
637 for (i = 0; i < byte_length; i++)
638 tdo_buffer[i] = flip_u32(usb_in_buffer[i], 8);
639
640 for (i = 0; i < pending_scan_results_length; i++) {
641 struct pending_scan_result *pending_scan_result =
642 &pending_scan_results_buffer[i];
643 uint8_t *buffer = pending_scan_result->buffer;
644 int length = pending_scan_result->length;
645 int first = pending_scan_result->first;
646 struct scan_command *command = pending_scan_result->command;
647
648 /* Copy to buffer */
649 buf_set_buf(tdo_buffer, first, buffer, 0, length);
650
651 DEBUG_JTAG_IO("pending scan result, length = %d", length);
652
653 #ifdef _DEBUG_USB_COMMS_
654 armjtagew_debug_buffer(buffer, byte_length);
655 #endif
656
657 if (jtag_read_buffer(buffer, command) != ERROR_OK) {
658 armjtagew_tap_init();
659 return ERROR_JTAG_QUEUE_FAILED;
660 }
661
662 if (pending_scan_result->buffer != NULL)
663 free(pending_scan_result->buffer);
664 }
665 } else {
666 LOG_ERROR("armjtagew_tap_execute, wrong result %d, expected %d",
667 result,
668 byte_length);
669 return ERROR_JTAG_QUEUE_FAILED;
670 }
671
672 armjtagew_tap_init();
673 }
674
675 return ERROR_OK;
676 }
677
678 /****************************************************************************
679 * JLink USB low-level functions */
680
681 static struct armjtagew *armjtagew_usb_open()
682 {
683 usb_init();
684
685 const uint16_t vids[] = { USB_VID, 0 };
686 const uint16_t pids[] = { USB_PID, 0 };
687 struct usb_dev_handle *dev;
688 if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
689 return NULL;
690
691 struct armjtagew *result = malloc(sizeof(struct armjtagew));
692 result->usb_handle = dev;
693
694 #if 0
695 /* usb_set_configuration required under win32 */
696 usb_set_configuration(dev, dev->config[0].bConfigurationValue);
697 #endif
698 usb_claim_interface(dev, 0);
699 #if 0
700 /*
701 * This makes problems under Mac OS X. And is not needed
702 * under Windows. Hopefully this will not break a linux build
703 */
704 usb_set_altinterface(dev, 0);
705 #endif
706 return result;
707 }
708
709 static void armjtagew_usb_close(struct armjtagew *armjtagew)
710 {
711 usb_close(armjtagew->usb_handle);
712 free(armjtagew);
713 }
714
715 /* Send a message and receive the reply. */
716 static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length)
717 {
718 int result;
719
720 result = armjtagew_usb_write(armjtagew, out_length);
721 if (result == out_length) {
722 result = armjtagew_usb_read(armjtagew, in_length);
723 if (result != in_length) {
724 LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
725 in_length,
726 result);
727 return -1;
728 }
729 } else {
730 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result);
731 return -1;
732 }
733 return 0;
734 }
735
736 /* Write data from out_buffer to USB. */
737 static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length)
738 {
739 int result;
740
741 if (out_length > ARMJTAGEW_OUT_BUFFER_SIZE) {
742 LOG_ERROR("armjtagew_write illegal out_length=%d (max=%d)",
743 out_length,
744 ARMJTAGEW_OUT_BUFFER_SIZE);
745 return -1;
746 }
747
748 result = usb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT, \
749 (char *)usb_out_buffer, out_length, ARMJTAGEW_USB_TIMEOUT);
750
751 DEBUG_JTAG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length, result);
752
753 #ifdef _DEBUG_USB_COMMS_
754 armjtagew_debug_buffer(usb_out_buffer, out_length);
755 #endif
756 return result;
757 }
758
759 /* Read data from USB into in_buffer. */
760 static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length)
761 {
762 int result = usb_bulk_read(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_IN, \
763 (char *)usb_in_buffer, exp_in_length, ARMJTAGEW_USB_TIMEOUT);
764
765 DEBUG_JTAG_IO("armjtagew_usb_read, result = %d", result);
766
767 #ifdef _DEBUG_USB_COMMS_
768 armjtagew_debug_buffer(usb_in_buffer, result);
769 #endif
770 return result;
771 }
772
773 #ifdef _DEBUG_USB_COMMS_
774 #define BYTES_PER_LINE 16
775
776 static void armjtagew_debug_buffer(uint8_t *buffer, int length)
777 {
778 char line[81];
779 char s[4];
780 int i;
781 int j;
782
783 for (i = 0; i < length; i += BYTES_PER_LINE) {
784 snprintf(line, 5, "%04x", i);
785 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
786 snprintf(s, 4, " %02x", buffer[j]);
787 strcat(line, s);
788 }
789 LOG_DEBUG("%s", line);
790
791 /* Prevent GDB timeout (writing to log might take some time) */
792 keep_alive();
793 }
794 }
795 #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)