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

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)