arm-jtag-ew: Declare interface as `jtag_only'
[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 .transports = jtag_only,
527
528 .execute_queue = armjtagew_execute_queue,
529 .speed = armjtagew_speed,
530 .speed_div = armjtagew_speed_div,
531 .khz = armjtagew_khz,
532 .init = armjtagew_init,
533 .quit = armjtagew_quit,
534 };
535
536 /***************************************************************************/
537 /* ARM-JTAG-EW tap functions */
538
539 /* 2048 is the max value we can use here */
540 #define ARMJTAGEW_TAP_BUFFER_SIZE 2048
541
542 static int tap_length;
543 static uint8_t tms_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
544 static uint8_t tdi_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
545 static uint8_t tdo_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
546
547 struct pending_scan_result {
548 int first; /* First bit position in tdo_buffer to read */
549 int length; /* Number of bits to read */
550 struct scan_command *command; /* Corresponding scan command */
551 uint8_t *buffer;
552 };
553
554 #define MAX_PENDING_SCAN_RESULTS 256
555
556 static int pending_scan_results_length;
557 static struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
558
559 static int last_tms;
560
561 static void armjtagew_tap_init(void)
562 {
563 tap_length = 0;
564 pending_scan_results_length = 0;
565 }
566
567 static void armjtagew_tap_ensure_space(int scans, int bits)
568 {
569 int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
570 int available_bits = ARMJTAGEW_TAP_BUFFER_SIZE * 8 - tap_length;
571
572 if (scans > available_scans || bits > available_bits)
573 {
574 armjtagew_tap_execute();
575 }
576 }
577
578 static void armjtagew_tap_append_step(int tms, int tdi)
579 {
580 last_tms = tms;
581 int index_local = tap_length / 8;
582
583 if (index_local < ARMJTAGEW_TAP_BUFFER_SIZE)
584 {
585 int bit_index = tap_length % 8;
586 uint8_t bit = 1 << bit_index;
587
588 if (tms)
589 {
590 tms_buffer[index_local] |= bit;
591 }
592 else
593 {
594 tms_buffer[index_local] &= ~bit;
595 }
596
597 if (tdi)
598 {
599 tdi_buffer[index_local] |= bit;
600 }
601 else
602 {
603 tdi_buffer[index_local] &= ~bit;
604 }
605
606 tap_length++;
607 }
608 else
609 {
610 LOG_ERROR("armjtagew_tap_append_step, overflow");
611 }
612 }
613
614 void armjtagew_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command)
615 {
616 struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[pending_scan_results_length];
617 int i;
618
619 pending_scan_result->first = tap_length;
620 pending_scan_result->length = length;
621 pending_scan_result->command = command;
622 pending_scan_result->buffer = buffer;
623
624 for (i = 0; i < length; i++)
625 {
626 armjtagew_tap_append_step((i < length-1 ? 0 : 1), (buffer[i/8] >> (i%8)) & 1);
627 }
628 pending_scan_results_length++;
629 }
630
631 /* Pad and send a tap sequence to the device, and receive the answer.
632 * For the purpose of padding we assume that we are in idle or pause state. */
633 static int armjtagew_tap_execute(void)
634 {
635 int byte_length;
636 int tms_offset;
637 int tdi_offset;
638 int i;
639 int result;
640
641 if (tap_length > 0)
642 {
643 /* Pad last byte so that tap_length is divisible by 8 */
644 while (tap_length % 8 != 0)
645 {
646 /* More of the last TMS value keeps us in the same state,
647 * analogous to free-running JTAG interfaces. */
648 armjtagew_tap_append_step(last_tms, 0);
649 }
650
651 byte_length = tap_length / 8;
652
653 usb_out_buffer[0] = CMD_TAP_SHIFT;
654 buf_set_u32(usb_out_buffer + 1, 0, 16, byte_length);
655
656 tms_offset = 3;
657 for (i = 0; i < byte_length; i++)
658 {
659 usb_out_buffer[tms_offset + i] = flip_u32(tms_buffer[i],8);
660 }
661
662 tdi_offset = tms_offset + byte_length;
663 for (i = 0; i < byte_length; i++)
664 {
665 usb_out_buffer[tdi_offset + i] = flip_u32(tdi_buffer[i],8);
666 }
667
668 result = armjtagew_usb_message(armjtagew_handle, 3 + 2 * byte_length, byte_length + 4);
669
670 if (result == 0)
671 {
672 int stat_local;
673
674 stat_local = (int)buf_get_u32(usb_in_buffer + byte_length, 0, 32);
675 if (stat_local) {
676 LOG_ERROR("armjtagew_tap_execute, emulator returned error code %d for a CMD_TAP_SHIFT command", stat_local);
677 return ERROR_JTAG_QUEUE_FAILED;
678 }
679
680 for (i = 0; i < byte_length; i++)
681 {
682 tdo_buffer[i] = flip_u32(usb_in_buffer[i],8);
683 }
684
685 for (i = 0; i < pending_scan_results_length; i++)
686 {
687 struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[i];
688 uint8_t *buffer = pending_scan_result->buffer;
689 int length = pending_scan_result->length;
690 int first = pending_scan_result->first;
691 struct scan_command *command = pending_scan_result->command;
692
693 /* Copy to buffer */
694 buf_set_buf(tdo_buffer, first, buffer, 0, length);
695
696 DEBUG_JTAG_IO("pending scan result, length = %d", length);
697
698 #ifdef _DEBUG_USB_COMMS_
699 armjtagew_debug_buffer(buffer, byte_length);
700 #endif
701
702 if (jtag_read_buffer(buffer, command) != ERROR_OK)
703 {
704 armjtagew_tap_init();
705 return ERROR_JTAG_QUEUE_FAILED;
706 }
707
708 if (pending_scan_result->buffer != NULL)
709 {
710 free(pending_scan_result->buffer);
711 }
712 }
713 }
714 else
715 {
716 LOG_ERROR("armjtagew_tap_execute, wrong result %d, expected %d", result, byte_length);
717 return ERROR_JTAG_QUEUE_FAILED;
718 }
719
720 armjtagew_tap_init();
721 }
722
723 return ERROR_OK;
724 }
725
726 /*****************************************************************************/
727 /* JLink USB low-level functions */
728
729 static struct armjtagew* armjtagew_usb_open()
730 {
731 usb_init();
732
733 const uint16_t vids[] = { USB_VID, 0 };
734 const uint16_t pids[] = { USB_PID, 0 };
735 struct usb_dev_handle *dev;
736 if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
737 return NULL;
738
739 struct armjtagew *result = malloc(sizeof(struct armjtagew));
740 result->usb_handle = dev;
741
742 #if 0
743 /* usb_set_configuration required under win32 */
744 usb_set_configuration(dev, dev->config[0].bConfigurationValue);
745 #endif
746 usb_claim_interface(dev, 0);
747 #if 0
748 /*
749 * This makes problems under Mac OS X. And is not needed
750 * under Windows. Hopefully this will not break a linux build
751 */
752 usb_set_altinterface(dev, 0);
753 #endif
754 return result;
755 }
756
757 static void armjtagew_usb_close(struct armjtagew *armjtagew)
758 {
759 usb_close(armjtagew->usb_handle);
760 free(armjtagew);
761 }
762
763 /* Send a message and receive the reply. */
764 static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length)
765 {
766 int result;
767
768 result = armjtagew_usb_write(armjtagew, out_length);
769 if (result == out_length)
770 {
771 result = armjtagew_usb_read(armjtagew, in_length);
772 if (result != in_length)
773 {
774 LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)", in_length, result);
775 return -1;
776 }
777 }
778 else
779 {
780 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result);
781 return -1;
782 }
783 return 0;
784 }
785
786 /* Write data from out_buffer to USB. */
787 static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length)
788 {
789 int result;
790
791 if (out_length > ARMJTAGEW_OUT_BUFFER_SIZE)
792 {
793 LOG_ERROR("armjtagew_write illegal out_length=%d (max=%d)", out_length, ARMJTAGEW_OUT_BUFFER_SIZE);
794 return -1;
795 }
796
797 result = usb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT, \
798 (char*)usb_out_buffer, out_length, ARMJTAGEW_USB_TIMEOUT);
799
800 DEBUG_JTAG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length, result);
801
802 #ifdef _DEBUG_USB_COMMS_
803 armjtagew_debug_buffer(usb_out_buffer, out_length);
804 #endif
805 return result;
806 }
807
808 /* Read data from USB into in_buffer. */
809 static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length)
810 {
811 int result = usb_bulk_read(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_IN, \
812 (char*)usb_in_buffer, exp_in_length, ARMJTAGEW_USB_TIMEOUT);
813
814 DEBUG_JTAG_IO("armjtagew_usb_read, result = %d", result);
815
816 #ifdef _DEBUG_USB_COMMS_
817 armjtagew_debug_buffer(usb_in_buffer, result);
818 #endif
819 return result;
820 }
821
822
823 #ifdef _DEBUG_USB_COMMS_
824 #define BYTES_PER_LINE 16
825
826 static void armjtagew_debug_buffer(uint8_t *buffer, int length)
827 {
828 char line[81];
829 char s[4];
830 int i;
831 int j;
832
833 for (i = 0; i < length; i += BYTES_PER_LINE)
834 {
835 snprintf(line, 5, "%04x", i);
836 for (j = i; j < i + BYTES_PER_LINE && j < length; j++)
837 {
838 snprintf(s, 4, " %02x", buffer[j]);
839 strcat(line, s);
840 }
841 LOG_DEBUG("%s", line);
842 }
843 }
844 #endif
845

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)