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

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)