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

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)