drivers/arm-jtag-ew: switch to libusb1
[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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <jtag/interface.h>
24 #include <jtag/commands.h>
25 #include "libusb_helper.h"
26
27 #define USB_VID 0x15ba
28 #define USB_PID 0x001e
29
30 #define ARMJTAGEW_EPT_BULK_OUT 0x01u
31 #define ARMJTAGEW_EPT_BULK_IN 0x82u
32
33 #define ARMJTAGEW_USB_TIMEOUT 2000
34
35 #define ARMJTAGEW_IN_BUFFER_SIZE (4*1024)
36 #define ARMJTAGEW_OUT_BUFFER_SIZE (4*1024)
37
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
49
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];
53
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,
60 enum scan_type type,
61 uint8_t *buffer,
62 int scan_size,
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);
67
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);
74
75 /* ARM-JTAG-EW lowlevel functions */
76 struct armjtagew {
77 struct libusb_device_handle *usb_handle;
78 };
79
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);
85
86 /* helper functions */
87 static int armjtagew_get_version_info(void);
88
89 #ifdef _DEBUG_USB_COMMS_
90 static void armjtagew_debug_buffer(uint8_t *buffer, int length);
91 #endif
92
93 static struct armjtagew *armjtagew_handle;
94
95 /**************************************************************************
96 * External interface implementation */
97
98 static int armjtagew_execute_queue(void)
99 {
100 struct jtag_command *cmd = jtag_command_queue;
101 int scan_size;
102 enum scan_type type;
103 uint8_t *buffer;
104
105 while (cmd != NULL) {
106 switch (cmd->type) {
107 case JTAG_RUNTEST:
108 LOG_DEBUG_IO("runtest %i cycles, end in %i",
109 cmd->cmd.runtest->num_cycles,
110 cmd->cmd.runtest->end_state);
111
112 armjtagew_end_state(cmd->cmd.runtest->end_state);
113 armjtagew_runtest(cmd->cmd.runtest->num_cycles);
114 break;
115
116 case JTAG_TLR_RESET:
117 LOG_DEBUG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
118
119 armjtagew_end_state(cmd->cmd.statemove->end_state);
120 armjtagew_state_move();
121 break;
122
123 case JTAG_PATHMOVE:
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]);
127
128 armjtagew_path_move(cmd->cmd.pathmove->num_states,
129 cmd->cmd.pathmove->path);
130 break;
131
132 case JTAG_SCAN:
133 LOG_DEBUG_IO("scan end in %i", cmd->cmd.scan->end_state);
134
135 armjtagew_end_state(cmd->cmd.scan->end_state);
136
137 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
138 LOG_DEBUG_IO("scan input, length = %d", scan_size);
139
140 #ifdef _DEBUG_USB_COMMS_
141 armjtagew_debug_buffer(buffer, (scan_size + 7) / 8);
142 #endif
143 type = jtag_scan_type(cmd->cmd.scan);
144 armjtagew_scan(cmd->cmd.scan->ir_scan,
145 type, buffer,
146 scan_size, cmd->cmd.scan);
147 break;
148
149 case JTAG_RESET:
150 LOG_DEBUG_IO("reset trst: %i srst %i",
151 cmd->cmd.reset->trst,
152 cmd->cmd.reset->srst);
153
154 armjtagew_tap_execute();
155
156 if (cmd->cmd.reset->trst == 1)
157 tap_set_state(TAP_RESET);
158 armjtagew_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
159 break;
160
161 case JTAG_SLEEP:
162 LOG_DEBUG_IO("sleep %" PRIu32, cmd->cmd.sleep->us);
163 armjtagew_tap_execute();
164 jtag_sleep(cmd->cmd.sleep->us);
165 break;
166
167 default:
168 LOG_ERROR("BUG: unknown JTAG command type encountered");
169 exit(-1);
170 }
171 cmd = cmd->next;
172 }
173
174 return armjtagew_tap_execute();
175 }
176
177 /* Sets speed in kHz. */
178 static int armjtagew_speed(int speed)
179 {
180 int result;
181 int speed_real;
182
183
184 usb_out_buffer[0] = CMD_SET_TCK_FREQUENCY;
185 buf_set_u32(usb_out_buffer + 1, 0, 32, speed*1000);
186
187 result = armjtagew_usb_message(armjtagew_handle, 5, 4);
188
189 if (result < 0) {
190 LOG_ERROR("ARM-JTAG-EW setting speed failed (%d)", result);
191 return ERROR_JTAG_DEVICE_ERROR;
192 }
193
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;
197 if (result < 0) {
198 LOG_ERROR("ARM-JTAG-EW getting speed failed (%d)", result);
199 return ERROR_JTAG_DEVICE_ERROR;
200 } else
201 LOG_INFO("Requested speed %dkHz, emulator reported %dkHz.", speed, speed_real);
202
203 return ERROR_OK;
204 }
205
206 static int armjtagew_khz(int khz, int *jtag_speed)
207 {
208 *jtag_speed = khz;
209
210 return ERROR_OK;
211 }
212
213 static int armjtagew_speed_div(int speed, int *khz)
214 {
215 *khz = speed;
216
217 return ERROR_OK;
218 }
219
220 static int armjtagew_init(void)
221 {
222 int check_cnt;
223
224 armjtagew_handle = armjtagew_usb_open();
225
226 if (armjtagew_handle == 0) {
227 LOG_ERROR(
228 "Cannot find ARM-JTAG-EW Interface! Please check connection and permissions.");
229 return ERROR_JTAG_INIT_FAILED;
230 }
231
232 check_cnt = 0;
233 while (check_cnt < 3) {
234 if (armjtagew_get_version_info() == ERROR_OK) {
235 /* attempt to get status */
236 armjtagew_get_status();
237 break;
238 }
239
240 check_cnt++;
241 }
242
243 if (check_cnt == 3)
244 LOG_INFO("ARM-JTAG-EW initial read failed, don't worry");
245
246 /* Initial JTAG speed (for reset and initialization): 32 kHz */
247 armjtagew_speed(32);
248
249 LOG_INFO("ARM-JTAG-EW JTAG Interface ready");
250
251 armjtagew_reset(0, 0);
252 armjtagew_tap_init();
253
254 return ERROR_OK;
255 }
256
257 static int armjtagew_quit(void)
258 {
259 armjtagew_usb_close(armjtagew_handle);
260 return ERROR_OK;
261 }
262
263 /**************************************************************************
264 * Queue command implementations */
265
266 static void armjtagew_end_state(tap_state_t state)
267 {
268 if (tap_is_state_stable(state))
269 tap_set_end_state(state);
270 else {
271 LOG_ERROR("BUG: %i is not a valid end state", state);
272 exit(-1);
273 }
274 }
275
276 /* Goes to the end state. */
277 static void armjtagew_state_move(void)
278 {
279 int i;
280 int tms = 0;
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());
283
284 for (i = 0; i < tms_count; i++) {
285 tms = (tms_scan >> i) & 1;
286 armjtagew_tap_append_step(tms, 0);
287 }
288
289 tap_set_state(tap_get_end_state());
290 }
291
292 static void armjtagew_path_move(int num_states, tap_state_t *path)
293 {
294 int i;
295
296 for (i = 0; i < num_states; i++) {
297 /*
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.
301 */
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);
306 else {
307 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
308 tap_state_name(tap_get_state()), tap_state_name(path[i]));
309 exit(-1);
310 }
311
312 tap_set_state(path[i]);
313 }
314
315 tap_set_end_state(tap_get_state());
316 }
317
318 static void armjtagew_runtest(int num_cycles)
319 {
320 int i;
321
322 tap_state_t saved_end_state = tap_get_end_state();
323
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();
328 }
329
330 /* execute num_cycles */
331 for (i = 0; i < num_cycles; i++)
332 armjtagew_tap_append_step(0, 0);
333
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();
338 }
339
340 static void armjtagew_scan(bool ir_scan,
341 enum scan_type type,
342 uint8_t *buffer,
343 int scan_size,
344 struct scan_command *command)
345 {
346 tap_state_t saved_end_state;
347
348 armjtagew_tap_ensure_space(1, scan_size + 8);
349
350 saved_end_state = tap_get_end_state();
351
352 /* Move to appropriate scan state */
353 armjtagew_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
354
355 /* Only move if we're not already there */
356 if (tap_get_state() != tap_get_end_state())
357 armjtagew_state_move();
358
359 armjtagew_end_state(saved_end_state);
360
361 /* Scan */
362 armjtagew_tap_append_scan(scan_size, buffer, command);
363
364 /* We are in Exit1, go to Pause */
365 armjtagew_tap_append_step(0, 0);
366
367 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
368
369 if (tap_get_state() != tap_get_end_state())
370 armjtagew_state_move();
371 }
372
373 static void armjtagew_reset(int trst, int srst)
374 {
375 const uint8_t trst_mask = (1u << 5);
376 const uint8_t srst_mask = (1u << 6);
377 uint8_t val = 0;
378 uint8_t outp_en = 0;
379 uint8_t change_mask = 0;
380 int result;
381
382 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
383
384 if (srst == 0) {
385 val |= srst_mask;
386 outp_en &= ~srst_mask; /* tristate */
387 change_mask |= srst_mask;
388 } else if (srst == 1) {
389 val &= ~srst_mask;
390 outp_en |= srst_mask;
391 change_mask |= srst_mask;
392 }
393
394 if (trst == 0) {
395 val |= trst_mask;
396 outp_en &= ~trst_mask; /* tristate */
397 change_mask |= trst_mask;
398 } else if (trst == 1) {
399 val &= ~trst_mask;
400 outp_en |= trst_mask;
401 change_mask |= trst_mask;
402 }
403
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);
409 if (result != 4)
410 LOG_ERROR("ARM-JTAG-EW TRST/SRST pin set failed failed (%d)", result);
411 }
412
413 static int armjtagew_get_status(void)
414 {
415 int result;
416
417 usb_out_buffer[0] = CMD_GET_TAPHW_STATE;
418 result = armjtagew_usb_message(armjtagew_handle, 1, 12);
419
420 if (result == 0) {
421 unsigned int u_tg = buf_get_u32(usb_in_buffer, 0, 16);
422 LOG_INFO(
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)),
428 usb_in_buffer[9],
429 usb_in_buffer[11] ? "OVERCURRENT" : "OK",
430 usb_in_buffer[10] ? "enabled" : "disabled");
431
432 if (u_tg < 1500)
433 LOG_ERROR("Vref too low. Check Target Power");
434 } else
435 LOG_ERROR("ARM-JTAG-EW command CMD_GET_TAPHW_STATE failed (%d)", result);
436
437 return ERROR_OK;
438 }
439
440 static int armjtagew_get_version_info(void)
441 {
442 int result;
443 char sn[16];
444 char auxinfo[257];
445
446 /* query hardware version */
447 usb_out_buffer[0] = CMD_GET_VERSION;
448 result = armjtagew_usb_message(armjtagew_handle, 1, 4 + 15 + 256);
449
450 if (result != 0) {
451 LOG_ERROR("ARM-JTAG-EW command CMD_GET_VERSION failed (%d)", result);
452 return ERROR_JTAG_DEVICE_ERROR;
453 }
454
455 memcpy(sn, usb_in_buffer + 4, 15);
456 sn[15] = '\0';
457 memcpy(auxinfo, usb_in_buffer + 4+15, 256);
458 auxinfo[256] = '\0';
459
460 LOG_INFO(
461 "ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s",
462 usb_in_buffer[1],
463 usb_in_buffer[0],
464 isgraph(usb_in_buffer[2]) ? usb_in_buffer[2] : 'X',
465 sn,
466 auxinfo);
467
468 if (1 != usb_in_buffer[1] || 6 != usb_in_buffer[0])
469 LOG_WARNING(
470 "ARM-JTAG-EW firmware version %d.%d is untested with this version of OpenOCD. You might experience unexpected behavior.",
471 usb_in_buffer[1],
472 usb_in_buffer[0]);
473 return ERROR_OK;
474 }
475
476 COMMAND_HANDLER(armjtagew_handle_armjtagew_info_command)
477 {
478 if (armjtagew_get_version_info() == ERROR_OK) {
479 /* attempt to get status */
480 armjtagew_get_status();
481 }
482
483 return ERROR_OK;
484 }
485
486 static const struct command_registration armjtagew_command_handlers[] = {
487 {
488 .name = "armjtagew_info",
489 .handler = &armjtagew_handle_armjtagew_info_command,
490 .mode = COMMAND_EXEC,
491 .help = "query armjtagew info",
492 .usage = "",
493 },
494 COMMAND_REGISTRATION_DONE
495 };
496
497 static struct jtag_interface armjtagew_interface = {
498 .execute_queue = armjtagew_execute_queue,
499 };
500
501 struct adapter_driver armjtagew_adapter_driver = {
502 .name = "arm-jtag-ew",
503 .transports = jtag_only,
504 .commands = armjtagew_command_handlers,
505
506 .init = armjtagew_init,
507 .quit = armjtagew_quit,
508 .speed = armjtagew_speed,
509 .khz = armjtagew_khz,
510 .speed_div = armjtagew_speed_div,
511
512 .jtag_ops = &armjtagew_interface,
513 };
514
515 /**************************************************************************
516 * ARM-JTAG-EW tap functions */
517
518 /* 2048 is the max value we can use here */
519 #define ARMJTAGEW_TAP_BUFFER_SIZE 2048
520
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];
525
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 */
530 uint8_t *buffer;
531 };
532
533 #define MAX_PENDING_SCAN_RESULTS 256
534
535 static int pending_scan_results_length;
536 static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
537
538 static int last_tms;
539
540 static void armjtagew_tap_init(void)
541 {
542 tap_length = 0;
543 pending_scan_results_length = 0;
544 }
545
546 static void armjtagew_tap_ensure_space(int scans, int bits)
547 {
548 int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
549 int available_bits = ARMJTAGEW_TAP_BUFFER_SIZE * 8 - tap_length;
550
551 if (scans > available_scans || bits > available_bits)
552 armjtagew_tap_execute();
553 }
554
555 static void armjtagew_tap_append_step(int tms, int tdi)
556 {
557 last_tms = tms;
558 int index_local = tap_length / 8;
559
560 if (index_local < ARMJTAGEW_TAP_BUFFER_SIZE) {
561 int bit_index = tap_length % 8;
562 uint8_t bit = 1 << bit_index;
563
564 if (tms)
565 tms_buffer[index_local] |= bit;
566 else
567 tms_buffer[index_local] &= ~bit;
568
569 if (tdi)
570 tdi_buffer[index_local] |= bit;
571 else
572 tdi_buffer[index_local] &= ~bit;
573
574 tap_length++;
575 } else
576 LOG_ERROR("armjtagew_tap_append_step, overflow");
577 }
578
579 void armjtagew_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command)
580 {
581 struct pending_scan_result *pending_scan_result =
582 &pending_scan_results_buffer[pending_scan_results_length];
583 int i;
584
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;
589
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++;
593 }
594
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)
598 {
599 int byte_length;
600 int tms_offset;
601 int tdi_offset;
602 int i;
603 int result;
604
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);
611 }
612
613 byte_length = tap_length / 8;
614
615 usb_out_buffer[0] = CMD_TAP_SHIFT;
616 buf_set_u32(usb_out_buffer + 1, 0, 16, byte_length);
617
618 tms_offset = 3;
619 for (i = 0; i < byte_length; i++)
620 usb_out_buffer[tms_offset + i] = flip_u32(tms_buffer[i], 8);
621
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);
625
626 result = armjtagew_usb_message(armjtagew_handle,
627 3 + 2 * byte_length,
628 byte_length + 4);
629
630 if (result == 0) {
631 int stat_local;
632
633 stat_local = (int)buf_get_u32(usb_in_buffer + byte_length, 0, 32);
634 if (stat_local) {
635 LOG_ERROR(
636 "armjtagew_tap_execute, emulator returned error code %d for a CMD_TAP_SHIFT command",
637 stat_local);
638 return ERROR_JTAG_QUEUE_FAILED;
639 }
640
641 for (i = 0; i < byte_length; i++)
642 tdo_buffer[i] = flip_u32(usb_in_buffer[i], 8);
643
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;
651
652 /* Copy to buffer */
653 buf_set_buf(tdo_buffer, first, buffer, 0, length);
654
655 LOG_DEBUG_IO("pending scan result, length = %d", length);
656
657 #ifdef _DEBUG_USB_COMMS_
658 armjtagew_debug_buffer(buffer, byte_length);
659 #endif
660
661 if (jtag_read_buffer(buffer, command) != ERROR_OK) {
662 armjtagew_tap_init();
663 return ERROR_JTAG_QUEUE_FAILED;
664 }
665
666 free(pending_scan_result->buffer);
667 }
668 } else {
669 LOG_ERROR("armjtagew_tap_execute, wrong result %d, expected %d",
670 result,
671 byte_length);
672 return ERROR_JTAG_QUEUE_FAILED;
673 }
674
675 armjtagew_tap_init();
676 }
677
678 return ERROR_OK;
679 }
680
681 /****************************************************************************
682 * JLink USB low-level functions */
683
684 static struct armjtagew *armjtagew_usb_open(void)
685 {
686 const uint16_t vids[] = { USB_VID, 0 };
687 const uint16_t pids[] = { USB_PID, 0 };
688 struct libusb_device_handle *dev;
689
690 if (jtag_libusb_open(vids, pids, NULL, &dev, NULL) != ERROR_OK)
691 return NULL;
692
693 struct armjtagew *result = malloc(sizeof(struct armjtagew));
694 result->usb_handle = dev;
695
696 #if 0
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);
702 #endif
703 libusb_claim_interface(dev, 0);
704 #if 0
705 /*
706 * This makes problems under Mac OS X. And is not needed
707 * under Windows. Hopefully this will not break a linux build
708 */
709 libusb_set_interface_alt_setting(dev, 0, 0);
710 #endif
711 return result;
712 }
713
714 static void armjtagew_usb_close(struct armjtagew *armjtagew)
715 {
716 libusb_close(armjtagew->usb_handle);
717 free(armjtagew);
718 }
719
720 /* Send a message and receive the reply. */
721 static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length)
722 {
723 int result;
724
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)",
730 in_length,
731 result);
732 return -1;
733 }
734 } else {
735 LOG_ERROR("jtag_libusb_bulk_write failed (requested=%d, result=%d)", out_length, result);
736 return -1;
737 }
738 return 0;
739 }
740
741 /* Write data from out_buffer to USB. */
742 static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length)
743 {
744 int result;
745 int transferred;
746
747 if (out_length > ARMJTAGEW_OUT_BUFFER_SIZE) {
748 LOG_ERROR("armjtagew_write illegal out_length=%d (max=%d)",
749 out_length,
750 ARMJTAGEW_OUT_BUFFER_SIZE);
751 return -1;
752 }
753
754 result = jtag_libusb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT,
755 (char *)usb_out_buffer, out_length, ARMJTAGEW_USB_TIMEOUT, &transferred);
756
757 LOG_DEBUG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length, result);
758
759 #ifdef _DEBUG_USB_COMMS_
760 armjtagew_debug_buffer(usb_out_buffer, out_length);
761 #endif
762 if (result != ERROR_OK)
763 return -1;
764 return transferred;
765 }
766
767 /* Read data from USB into in_buffer. */
768 static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length)
769 {
770 int transferred;
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);
773
774 LOG_DEBUG_IO("armjtagew_usb_read, result = %d", result);
775
776 #ifdef _DEBUG_USB_COMMS_
777 armjtagew_debug_buffer(usb_in_buffer, result);
778 #endif
779 if (result != ERROR_OK)
780 return -1;
781 return transferred;
782 }
783
784 #ifdef _DEBUG_USB_COMMS_
785 #define BYTES_PER_LINE 16
786
787 static void armjtagew_debug_buffer(uint8_t *buffer, int length)
788 {
789 char line[81];
790 char s[4];
791 int i;
792 int j;
793
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]);
798 strcat(line, s);
799 }
800 LOG_DEBUG("%s", line);
801
802 /* Prevent GDB timeout (writing to log might take some time) */
803 keep_alive();
804 }
805 }
806 #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)