armjtagew_jtag_t -> struct armjtagew
[openocd.git] / src / jtag / 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 "interface.h"
26 #include "commands.h"
27 #include <usb.h>
28
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
42 /* USB command request codes. */
43 #define CMD_GET_VERSION 0x00
44 #define CMD_SELECT_DPIMPL 0x10
45 #define CMD_SET_TCK_FREQUENCY 0x11
46 #define CMD_GET_TCK_FREQUENCY 0x12
47 #define CMD_MEASURE_MAX_TCK_FREQ 0x15
48 #define CMD_MEASURE_RTCK_RESPONSE 0x16
49 #define CMD_TAP_SHIFT 0x17
50 #define CMD_SET_TAPHW_STATE 0x20
51 #define CMD_GET_TAPHW_STATE 0x21
52 #define CMD_TGPWR_SETUP 0x22
53
54 /* Global USB buffers */
55 static uint8_t usb_in_buffer[ARMJTAGEW_IN_BUFFER_SIZE];
56 static uint8_t usb_out_buffer[ARMJTAGEW_OUT_BUFFER_SIZE];
57
58 /* External interface functions */
59 static int armjtagew_execute_queue(void);
60 static int armjtagew_speed(int speed);
61 static int armjtagew_khz(int khz, int *jtag_speed);
62 static int armjtagew_register_commands(struct command_context_s *cmd_ctx);
63 static int armjtagew_init(void);
64 static int armjtagew_quit(void);
65
66 /* CLI command handler functions */
67 static int armjtagew_handle_armjtagew_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
68
69 /* Queue command functions */
70 static void armjtagew_end_state(tap_state_t state);
71 static void armjtagew_state_move(void);
72 static void armjtagew_path_move(int num_states, tap_state_t *path);
73 static void armjtagew_runtest(int num_cycles);
74 static void armjtagew_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, scan_command_t *command);
75 static void armjtagew_reset(int trst, int srst);
76 //static void armjtagew_simple_command(uint8_t command);
77 static int armjtagew_get_status(void);
78
79 /* tap buffer functions */
80 static void armjtagew_tap_init(void);
81 static int armjtagew_tap_execute(void);
82 static void armjtagew_tap_ensure_space(int scans, int bits);
83 static void armjtagew_tap_append_step(int tms, int tdi);
84 static void armjtagew_tap_append_scan(int length, uint8_t *buffer, scan_command_t *command);
85
86 /* ARM-JTAG-EW lowlevel functions */
87 struct armjtagew {
88 struct usb_dev_handle* usb_handle;
89 };
90
91 static struct armjtagew *armjtagew_usb_open(void);
92 static void armjtagew_usb_close(struct armjtagew *armjtagew);
93 static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length);
94 static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length);
95 static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length);
96
97 /* helper functions */
98 static int armjtagew_get_version_info(void);
99
100 #ifdef _DEBUG_USB_COMMS_
101 static void armjtagew_debug_buffer(uint8_t *buffer, int length);
102 #endif
103
104 static struct armjtagew* armjtagew_handle;
105
106
107
108 /***************************************************************************/
109 /* External interface implementation */
110
111 struct jtag_interface armjtagew_interface =
112 {
113 .name = "arm-jtag-ew",
114 .execute_queue = armjtagew_execute_queue,
115 .speed = armjtagew_speed,
116 .khz = armjtagew_khz,
117 .register_commands = armjtagew_register_commands,
118 .init = armjtagew_init,
119 .quit = armjtagew_quit
120 };
121
122
123 static int armjtagew_execute_queue(void)
124 {
125 jtag_command_t *cmd = jtag_command_queue;
126 int scan_size;
127 enum scan_type type;
128 uint8_t *buffer;
129
130 while (cmd != NULL)
131 {
132 switch (cmd->type)
133 {
134 case JTAG_RUNTEST:
135 DEBUG_JTAG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, \
136 cmd->cmd.runtest->end_state);
137
138 armjtagew_end_state(cmd->cmd.runtest->end_state);
139 armjtagew_runtest(cmd->cmd.runtest->num_cycles);
140 break;
141
142 case JTAG_STATEMOVE:
143 DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
144
145 armjtagew_end_state(cmd->cmd.statemove->end_state);
146 armjtagew_state_move();
147 break;
148
149 case JTAG_PATHMOVE:
150 DEBUG_JTAG_IO("pathmove: %i states, end in %i", \
151 cmd->cmd.pathmove->num_states, \
152 cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
153
154 armjtagew_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
155 break;
156
157 case JTAG_SCAN:
158 DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state);
159
160 armjtagew_end_state(cmd->cmd.scan->end_state);
161
162 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
163 DEBUG_JTAG_IO("scan input, length = %d", scan_size);
164
165 #ifdef _DEBUG_USB_COMMS_
166 armjtagew_debug_buffer(buffer, (scan_size + 7) / 8);
167 #endif
168 type = jtag_scan_type(cmd->cmd.scan);
169 armjtagew_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan);
170 break;
171
172 case JTAG_RESET:
173 DEBUG_JTAG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
174
175 armjtagew_tap_execute();
176
177 if (cmd->cmd.reset->trst == 1)
178 {
179 tap_set_state(TAP_RESET);
180 }
181 armjtagew_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
182 break;
183
184 case JTAG_SLEEP:
185 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
186 armjtagew_tap_execute();
187 jtag_sleep(cmd->cmd.sleep->us);
188 break;
189
190 default:
191 LOG_ERROR("BUG: unknown JTAG command type encountered");
192 exit(-1);
193 }
194 cmd = cmd->next;
195 }
196
197 return armjtagew_tap_execute();
198 }
199
200
201 /* Sets speed in kHz. */
202 static int armjtagew_speed(int speed)
203 {
204 int result;
205 int speed_real;
206
207
208 usb_out_buffer[0] = CMD_SET_TCK_FREQUENCY;
209 buf_set_u32(usb_out_buffer + 1, 0, 32, speed);
210
211 result = armjtagew_usb_message(armjtagew_handle, 4, 4);
212
213 if (result < 0)
214 {
215 LOG_ERROR("ARM-JTAG-EW setting speed failed (%d)", result);
216 return ERROR_JTAG_DEVICE_ERROR;
217 }
218
219 usb_out_buffer[0] = CMD_GET_TCK_FREQUENCY;
220 result = armjtagew_usb_message(armjtagew_handle, 1, 4);
221 speed_real = (int)buf_get_u32(usb_in_buffer,0,32);
222 if (result < 0)
223 {
224 LOG_ERROR("ARM-JTAG-EW getting speed failed (%d)", result);
225 return ERROR_JTAG_DEVICE_ERROR;
226 }
227 else
228 {
229 LOG_INFO("Requested speed %dkHz, emulator reported %dkHz.", speed, speed_real);
230 }
231
232 return ERROR_OK;
233 }
234
235
236 static int armjtagew_khz(int khz, int *jtag_speed)
237 {
238 *jtag_speed = khz;
239
240 return ERROR_OK;
241 }
242
243 static int armjtagew_register_commands(struct command_context_s *cmd_ctx)
244 {
245 register_command(cmd_ctx, NULL, "armjtagew_info", armjtagew_handle_armjtagew_info_command, COMMAND_EXEC,
246 "query armjtagew info");
247 return ERROR_OK;
248 }
249
250 static int armjtagew_init(void)
251 {
252 int check_cnt;
253
254 armjtagew_handle = armjtagew_usb_open();
255
256 if (armjtagew_handle == 0)
257 {
258 LOG_ERROR("Cannot find ARM-JTAG-EW Interface! Please check connection and permissions.");
259 return ERROR_JTAG_INIT_FAILED;
260 }
261
262 check_cnt = 0;
263 while (check_cnt < 3)
264 {
265 if (armjtagew_get_version_info() == ERROR_OK)
266 {
267 /* attempt to get status */
268 armjtagew_get_status();
269 break;
270 }
271
272 check_cnt++;
273 }
274
275 if (check_cnt == 3)
276 {
277 LOG_INFO("ARM-JTAG-EW initial read failed, don't worry");
278 }
279
280 LOG_INFO("ARM-JTAG-EW JTAG Interface ready");
281
282 armjtagew_reset(0, 0);
283 armjtagew_tap_init();
284
285 return ERROR_OK;
286 }
287
288 static int armjtagew_quit(void)
289 {
290 armjtagew_usb_close(armjtagew_handle);
291 return ERROR_OK;
292 }
293
294 /***************************************************************************/
295 /* Queue command implementations */
296
297 static void armjtagew_end_state(tap_state_t state)
298 {
299 if (tap_is_state_stable(state))
300 {
301 tap_set_end_state(state);
302 }
303 else
304 {
305 LOG_ERROR("BUG: %i is not a valid end state", state);
306 exit(-1);
307 }
308 }
309
310 /* Goes to the end state. */
311 static void armjtagew_state_move(void)
312 {
313 int i;
314 int tms = 0;
315 uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
316 int tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
317
318 for (i = 0; i < tms_count; i++)
319 {
320 tms = (tms_scan >> i) & 1;
321 armjtagew_tap_append_step(tms, 0);
322 }
323
324 tap_set_state(tap_get_end_state());
325 }
326
327 static void armjtagew_path_move(int num_states, tap_state_t *path)
328 {
329 int i;
330
331 for (i = 0; i < num_states; i++)
332 {
333 /*
334 * TODO: The ARM-JTAG-EW hardware delays TDI with 3 TCK cycles when in RTCK mode.
335 * Either handle that here, or update the documentation with examples
336 * how to fix that in the configuration files.
337 */
338 if (path[i] == tap_state_transition(tap_get_state(), false))
339 {
340 armjtagew_tap_append_step(0, 0);
341 }
342 else if (path[i] == tap_state_transition(tap_get_state(), true))
343 {
344 armjtagew_tap_append_step(1, 0);
345 }
346 else
347 {
348 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(path[i]));
349 exit(-1);
350 }
351
352 tap_set_state(path[i]);
353 }
354
355 tap_set_end_state(tap_get_state());
356 }
357
358 static void armjtagew_runtest(int num_cycles)
359 {
360 int i;
361
362 tap_state_t saved_end_state = tap_get_end_state();
363
364 /* only do a state_move when we're not already in IDLE */
365 if (tap_get_state() != TAP_IDLE)
366 {
367 armjtagew_end_state(TAP_IDLE);
368 armjtagew_state_move();
369 }
370
371 /* execute num_cycles */
372 for (i = 0; i < num_cycles; i++)
373 {
374 armjtagew_tap_append_step(0, 0);
375 }
376
377 /* finish in end_state */
378 armjtagew_end_state(saved_end_state);
379 if (tap_get_state() != tap_get_end_state())
380 {
381 armjtagew_state_move();
382 }
383 }
384
385 static void armjtagew_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, scan_command_t *command)
386 {
387 tap_state_t saved_end_state;
388
389 armjtagew_tap_ensure_space(1, scan_size + 8);
390
391 saved_end_state = tap_get_end_state();
392
393 /* Move to appropriate scan state */
394 armjtagew_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
395
396 armjtagew_state_move();
397 armjtagew_end_state(saved_end_state);
398
399 /* Scan */
400 armjtagew_tap_append_scan(scan_size, buffer, command);
401
402 /* We are in Exit1, go to Pause */
403 armjtagew_tap_append_step(0, 0);
404
405 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
406
407 if (tap_get_state() != tap_get_end_state())
408 {
409 armjtagew_state_move();
410 }
411 }
412
413 static void armjtagew_reset(int trst, int srst)
414 {
415 const uint8_t trst_mask = (1u << 5);
416 const uint8_t srst_mask = (1u << 6);
417 uint8_t val = 0;
418 uint8_t outp_en = 0;
419 uint8_t change_mask = 0;
420 int result;
421
422 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
423
424 if (srst == 0)
425 {
426 val |= srst_mask;
427 outp_en &= ~srst_mask; /* tristate */
428 change_mask |= srst_mask;
429 }
430 else if (srst == 1)
431 {
432 val &= ~srst_mask;
433 outp_en |= srst_mask;
434 change_mask |= srst_mask;
435 }
436
437 if (trst == 0)
438 {
439 val |= trst_mask;
440 outp_en &= ~trst_mask; /* tristate */
441 change_mask |= trst_mask;
442 }
443 else if (trst == 1)
444 {
445 val &= ~trst_mask;
446 outp_en |= trst_mask;
447 change_mask |= trst_mask;
448 }
449
450 usb_out_buffer[0] = CMD_SET_TAPHW_STATE;
451 usb_out_buffer[1] = val;
452 usb_out_buffer[2] = outp_en;
453 usb_out_buffer[3] = change_mask;
454 result = armjtagew_usb_write(armjtagew_handle, 4);
455 if (result != 4)
456 {
457 LOG_ERROR("ARM-JTAG-EW TRST/SRST pin set failed failed (%d)", result);
458 }
459 }
460
461
462 static int armjtagew_get_status(void)
463 {
464 int result;
465
466 usb_out_buffer[0] = CMD_GET_TAPHW_STATE;
467 result = armjtagew_usb_message(armjtagew_handle, 1, 12);
468
469 if (result == 0)
470 {
471 unsigned int u_tg = buf_get_u32(usb_in_buffer, 0, 16);
472 LOG_INFO("U_tg = %d mV, U_aux = %d mV, U_tgpwr = %d mV, I_tgpwr = %d mA, D1 = %d, Target power %s %s\n",
473 (int)(buf_get_u32(usb_in_buffer + 0, 0, 16)),
474 (int)(buf_get_u32(usb_in_buffer + 2, 0, 16)),
475 (int)(buf_get_u32(usb_in_buffer + 4, 0, 16)),
476 (int)(buf_get_u32(usb_in_buffer + 6, 0, 16)),
477 usb_in_buffer[9],
478 usb_in_buffer[11] ? "OVERCURRENT" : "OK",
479 usb_in_buffer[10] ? "enabled" : "disabled");
480
481 if (u_tg < 1500)
482 {
483 LOG_ERROR("Vref too low. Check Target Power\n");
484 }
485 }
486 else
487 {
488 LOG_ERROR("ARM-JTAG-EW command CMD_GET_TAPHW_STATE failed (%d)\n", result);
489 }
490
491 return ERROR_OK;
492 }
493
494 static int armjtagew_get_version_info(void)
495 {
496 int result;
497 char sn[16];
498 char auxinfo[257];
499
500 /* query hardware version */
501 usb_out_buffer[0] = CMD_GET_VERSION;
502 result = armjtagew_usb_message(armjtagew_handle, 1, 4 + 15 + 256);
503
504 if (result != 0)
505 {
506 LOG_ERROR("ARM-JTAG-EW command CMD_GET_VERSION failed (%d)\n", result);
507 return ERROR_JTAG_DEVICE_ERROR;
508 }
509
510
511 memcpy(sn, usb_in_buffer + 4, 15);
512 sn[15] = '\0';
513 memcpy(auxinfo, usb_in_buffer + 4+15, 256);
514 auxinfo[256] = '\0';
515
516 LOG_INFO("ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s", \
517 usb_in_buffer[1], usb_in_buffer[0], \
518 isgraph(usb_in_buffer[2]) ? usb_in_buffer[2] : 'X', \
519 sn, auxinfo);
520 return ERROR_OK;
521 }
522
523 static int armjtagew_handle_armjtagew_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
524 {
525 if (armjtagew_get_version_info() == ERROR_OK)
526 {
527 /* attempt to get status */
528 armjtagew_get_status();
529 }
530
531 return ERROR_OK;
532 }
533
534 /***************************************************************************/
535 /* ARM-JTAG-EW tap functions */
536
537 /* 2048 is the max value we can use here */
538 #define ARMJTAGEW_TAP_BUFFER_SIZE 2048
539
540 static int tap_length;
541 static uint8_t tms_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
542 static uint8_t tdi_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
543 static uint8_t tdo_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];
544
545 typedef struct
546 {
547 int first; /* First bit position in tdo_buffer to read */
548 int length; /* Number of bits to read */
549 scan_command_t *command; /* Corresponding scan command */
550 uint8_t *buffer;
551 } pending_scan_result_t;
552
553 #define MAX_PENDING_SCAN_RESULTS 256
554
555 static int pending_scan_results_length;
556 static pending_scan_result_t 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 = tap_length / 8;
581
582 if (index < 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] |= bit;
590 }
591 else
592 {
593 tms_buffer[index] &= ~bit;
594 }
595
596 if (tdi)
597 {
598 tdi_buffer[index] |= bit;
599 }
600 else
601 {
602 tdi_buffer[index] &= ~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, scan_command_t *command)
614 {
615 pending_scan_result_t *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;
672
673 stat = (int)buf_get_u32(usb_in_buffer + byte_length, 0, 32);
674 if (stat) {
675 LOG_ERROR("armjtagew_tap_execute, emulator returned error code %d for a CMD_TAP_SHIFT command", stat);
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 pending_scan_result_t *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 scan_command_t *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 struct usb_bus *busses;
731 struct usb_bus *bus;
732 struct usb_device *dev;
733
734 struct armjtagew *result;
735
736 result = (struct armjtagew*) malloc(sizeof(struct armjtagew));
737
738 usb_init();
739 usb_find_busses();
740 usb_find_devices();
741
742 busses = usb_get_busses();
743
744 /* find armjtagew device in usb bus */
745
746 for (bus = busses; bus; bus = bus->next)
747 {
748 for (dev = bus->devices; dev; dev = dev->next)
749 {
750 if ((dev->descriptor.idVendor == USB_VID) && (dev->descriptor.idProduct == USB_PID))
751 {
752 result->usb_handle = usb_open(dev);
753
754 #if 0
755 /* usb_set_configuration required under win32 */
756 usb_set_configuration(result->usb_handle, dev->config[0].bConfigurationValue);
757 #endif
758 usb_claim_interface(result->usb_handle, 0);
759
760 #if 0
761 /*
762 * This makes problems under Mac OS X. And is not needed
763 * under Windows. Hopefully this will not break a linux build
764 */
765 usb_set_altinterface(result->usb_handle, 0);
766 #endif
767 return result;
768 }
769 }
770 }
771
772 free(result);
773 return NULL;
774 }
775
776 static void armjtagew_usb_close(struct armjtagew *armjtagew)
777 {
778 usb_close(armjtagew->usb_handle);
779 free(armjtagew);
780 }
781
782 /* Send a message and receive the reply. */
783 static int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length)
784 {
785 int result;
786
787 result = armjtagew_usb_write(armjtagew, out_length);
788 if (result == out_length)
789 {
790 result = armjtagew_usb_read(armjtagew, in_length);
791 if (result != in_length)
792 {
793 LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)", in_length, result);
794 return -1;
795 }
796 }
797 else
798 {
799 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)", out_length, result);
800 return -1;
801 }
802 return 0;
803 }
804
805 /* Write data from out_buffer to USB. */
806 static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length)
807 {
808 int result;
809
810 if (out_length > ARMJTAGEW_OUT_BUFFER_SIZE)
811 {
812 LOG_ERROR("armjtagew_write illegal out_length=%d (max=%d)", out_length, ARMJTAGEW_OUT_BUFFER_SIZE);
813 return -1;
814 }
815
816 result = usb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT, \
817 (char*)usb_out_buffer, out_length, ARMJTAGEW_USB_TIMEOUT);
818
819 DEBUG_JTAG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length, result);
820
821 #ifdef _DEBUG_USB_COMMS_
822 armjtagew_debug_buffer(usb_out_buffer, out_length);
823 #endif
824 return result;
825 }
826
827 /* Read data from USB into in_buffer. */
828 static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length)
829 {
830 int result = usb_bulk_read(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_IN, \
831 (char*)usb_in_buffer, exp_in_length, ARMJTAGEW_USB_TIMEOUT);
832
833 DEBUG_JTAG_IO("armjtagew_usb_read, result = %d", result);
834
835 #ifdef _DEBUG_USB_COMMS_
836 armjtagew_debug_buffer(usb_in_buffer, result);
837 #endif
838 return result;
839 }
840
841
842 #ifdef _DEBUG_USB_COMMS_
843 #define BYTES_PER_LINE 16
844
845 static void armjtagew_debug_buffer(uint8_t *buffer, int length)
846 {
847 char line[81];
848 char s[4];
849 int i;
850 int j;
851
852 for (i = 0; i < length; i += BYTES_PER_LINE)
853 {
854 snprintf(line, 5, "%04x", i);
855 for (j = i; j < i + BYTES_PER_LINE && j < length; j++)
856 {
857 snprintf(s, 4, " %02x", buffer[j]);
858 strcat(line, s);
859 }
860 LOG_DEBUG("%s", line);
861 }
862 }
863 #endif
864

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)