versaloon cleanup patch
[openocd.git] / src / jtag / drivers / vsllink.c
1 /***************************************************************************
2 * Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
19
20 /* Versaloon is a programming tool for multiple MCUs.
21 * It's distributed under GPLv3.
22 * You can find it at http://www.SimonQian.com/en/Versaloon.
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <jtag/interface.h>
30 #include <jtag/commands.h>
31 #include "usb_common.h"
32
33 //#define _VSLLINK_IN_DEBUG_MODE_
34
35 static uint16_t vsllink_usb_vid;
36 static uint16_t vsllink_usb_pid;
37 static uint8_t vsllink_usb_bulkout;
38 static uint8_t vsllink_usb_bulkin;
39 static uint8_t vsllink_usb_interface;
40 static int VSLLINK_USB_TIMEOUT = 1000;
41
42 static int vsllink_tms_offset;
43
44 /* Global USB buffers */
45 static uint8_t *vsllink_usb_in_buffer;
46 static uint8_t *vsllink_usb_out_buffer;
47 static int vsllink_buffer_size = 128;
48
49 /* Constants for Versaloon command */
50 #define VERSALOON_GET_INFO 0x00
51 #define VERSALOON_GET_TVCC 0x01
52
53 /* Constants for VSLLink command */
54 #define VSLLINK_CMD_CONN 0x80
55 #define VSLLINK_CMD_DISCONN 0x81
56 #define VSLLINK_CMD_SET_SPEED 0x82
57 #define VSLLINK_CMD_SET_PORT 0x90
58 #define VSLLINK_CMD_GET_PORT 0x91
59 #define VSLLINK_CMD_SET_PORTDIR 0x92
60 #define VSLLINK_CMD_HW_JTAGSEQCMD 0xA0
61 #define VSLLINK_CMD_HW_JTAGHLCMD 0xA1
62 #define VSLLINK_CMD_HW_SWDCMD 0xA2
63 #define VSLLINK_CMD_HW_JTAGRAWCMD 0xA3
64
65 #define VSLLINK_CMDJTAGSEQ_TMSBYTE 0x00
66 #define VSLLINK_CMDJTAGSEQ_TMSCLOCK 0x40
67 #define VSLLINK_CMDJTAGSEQ_SCAN 0x80
68
69 #define VSLLINK_CMDJTAGSEQ_CMDMSK 0xC0
70 #define VSLLINK_CMDJTAGSEQ_LENMSK 0x3F
71
72 #define JTAG_PINMSK_SRST (1 << 0)
73 #define JTAG_PINMSK_TRST (1 << 1)
74 #define JTAG_PINMSK_USR1 (1 << 2)
75 #define JTAG_PINMSK_USR2 (1 << 3)
76 #define JTAG_PINMSK_TCK (1 << 4)
77 #define JTAG_PINMSK_TMS (1 << 5)
78 #define JTAG_PINMSK_TDI (1 << 6)
79 #define JTAG_PINMSK_TDO (1 << 7)
80
81 struct pending_scan_result {
82 int src_offset;
83 int dest_offset;
84 int length; /* Number of bits to read */
85 struct scan_command *command; /* Corresponding scan command */
86 uint8_t *buffer;
87 bool last; /* indicate the last scan pending */
88 };
89
90 #define MAX_PENDING_SCAN_RESULTS 256
91
92 static int pending_scan_results_length;
93 static struct pending_scan_result
94 pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
95
96 /* Queue command functions */
97 static void vsllink_end_state(tap_state_t state);
98 static void vsllink_state_move(void);
99 static void vsllink_path_move(int num_states, tap_state_t *path);
100 static void vsllink_runtest(int num_cycles);
101 static void vsllink_stableclocks(int num_cycles, int tms);
102 static void vsllink_scan(bool ir_scan, enum scan_type type,
103 uint8_t *buffer, int scan_size, struct scan_command *command);
104 static void vsllink_reset(int trst, int srst);
105 static void vsllink_simple_command(uint8_t command);
106
107 /* VSLLink tap buffer functions */
108 static void vsllink_tap_append_step(int tms, int tdi);
109 static void vsllink_tap_init(void);
110 static int vsllink_tap_execute(void);
111 static void vsllink_tap_ensure_pending(int scans);
112 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
113 struct scan_command *command);
114
115 /* VSLLink lowlevel functions */
116 struct vsllink {
117 struct usb_dev_handle *usb_handle;
118 };
119
120 static struct vsllink *vsllink_usb_open(void);
121 static void vsllink_usb_close(struct vsllink *vsllink);
122 static int vsllink_usb_message(struct vsllink *vsllink, int out_length,
123 int in_length);
124 static int vsllink_usb_write(struct vsllink *vsllink, int out_length);
125 static int vsllink_usb_read(struct vsllink *vsllink);
126
127 #if defined _DEBUG_USB_COMMS_ || defined _DEBUG_JTAG_IO_
128 static void vsllink_debug_buffer(uint8_t *buffer, int length);
129 #endif
130
131 static int tap_length;
132 static int tap_buffer_size;
133 static uint8_t *tms_buffer;
134 static uint8_t *tdi_buffer;
135 static uint8_t *tdo_buffer;
136
137 static struct vsllink *vsllink_handle;
138
139 static void reset_command_pointer(void)
140 {
141 tap_length = 0;
142 }
143
144 static int vsllink_execute_queue(void)
145 {
146 struct jtag_command *cmd = jtag_command_queue;
147 int scan_size;
148 enum scan_type type;
149 uint8_t *buffer;
150
151 DEBUG_JTAG_IO("-------------------------------------"
152 " vsllink "
153 "-------------------------------------");
154
155 reset_command_pointer();
156 while (cmd != NULL) {
157 switch (cmd->type) {
158 case JTAG_RUNTEST:
159 DEBUG_JTAG_IO("runtest %i cycles, end in %s",
160 cmd->cmd.runtest->num_cycles,
161 tap_state_name(cmd->cmd.runtest
162 ->end_state));
163
164 vsllink_end_state(cmd->cmd.runtest->end_state);
165 vsllink_runtest(cmd->cmd.runtest->num_cycles);
166 break;
167
168 case JTAG_STATEMOVE:
169 DEBUG_JTAG_IO("statemove end in %s",
170 tap_state_name(cmd->cmd.statemove
171 ->end_state));
172
173 vsllink_end_state(cmd->cmd.statemove
174 ->end_state);
175 vsllink_state_move();
176 break;
177
178 case JTAG_PATHMOVE:
179 DEBUG_JTAG_IO("pathmove: %i states, end in %s",
180 cmd->cmd.pathmove->num_states,
181 tap_state_name(cmd->cmd.pathmove
182 ->path[cmd->cmd.pathmove
183 ->num_states - 1]));
184
185 vsllink_path_move(
186 cmd->cmd.pathmove->num_states,
187 cmd->cmd.pathmove->path);
188 break;
189
190 case JTAG_SCAN:
191 vsllink_end_state(cmd->cmd.scan->end_state);
192
193 scan_size = jtag_build_buffer(
194 cmd->cmd.scan, &buffer);
195
196 if (cmd->cmd.scan->ir_scan)
197 DEBUG_JTAG_IO(
198 "JTAG Scan write IR(%d bits), "
199 "end in %s:",
200 scan_size,
201 tap_state_name(cmd->cmd.scan
202 ->end_state));
203
204 else
205 DEBUG_JTAG_IO(
206 "JTAG Scan write DR(%d bits), "
207 "end in %s:",
208 scan_size,
209 tap_state_name(cmd->cmd.scan
210 ->end_state));
211
212 #ifdef _DEBUG_JTAG_IO_
213 vsllink_debug_buffer(buffer,
214 DIV_ROUND_UP(scan_size, 8));
215 #endif
216
217 type = jtag_scan_type(cmd->cmd.scan);
218
219 vsllink_scan(cmd->cmd.scan->ir_scan,
220 type, buffer, scan_size,
221 cmd->cmd.scan);
222 break;
223
224 case JTAG_RESET:
225 DEBUG_JTAG_IO("reset trst: %i srst %i",
226 cmd->cmd.reset->trst,
227 cmd->cmd.reset->srst);
228
229 vsllink_tap_execute();
230
231 if (cmd->cmd.reset->trst == 1)
232 tap_set_state(TAP_RESET);
233
234 vsllink_reset(cmd->cmd.reset->trst,
235 cmd->cmd.reset->srst);
236 break;
237
238 case JTAG_SLEEP:
239 DEBUG_JTAG_IO("sleep %i", cmd->cmd.sleep->us);
240 vsllink_tap_execute();
241 jtag_sleep(cmd->cmd.sleep->us);
242 break;
243
244 case JTAG_STABLECLOCKS:
245 DEBUG_JTAG_IO("add %d clocks",
246 cmd->cmd.stableclocks->num_cycles);
247 switch (tap_get_state()) {
248 case TAP_RESET:
249 /* tms must be '1' to stay
250 * n TAP_RESET mode
251 */
252 scan_size = 1;
253 break;
254 case TAP_DRSHIFT:
255 case TAP_IDLE:
256 case TAP_DRPAUSE:
257 case TAP_IRSHIFT:
258 case TAP_IRPAUSE:
259 /* else, tms should be '0' */
260 scan_size = 0;
261 break;
262 /* above stable states are OK */
263 default:
264 LOG_ERROR("jtag_add_clocks() "
265 "in non-stable state \"%s\"",
266 tap_state_name(tap_get_state())
267 );
268 exit(-1);
269 }
270 vsllink_stableclocks(cmd->cmd.stableclocks
271 ->num_cycles, scan_size);
272 break;
273
274 default:
275 LOG_ERROR("BUG: unknown JTAG command type "
276 "encountered: %d", cmd->type);
277 exit(-1);
278 }
279 cmd = cmd->next;
280 }
281
282 return vsllink_tap_execute();
283 }
284
285 static int vsllink_speed(int speed)
286 {
287 int result;
288
289 vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_SPEED;
290 vsllink_usb_out_buffer[1] = (speed >> 0) & 0xff;
291 vsllink_usb_out_buffer[2] = (speed >> 8) & 0xFF;
292
293 result = vsllink_usb_write(vsllink_handle, 3);
294
295 if (result == 3)
296 return ERROR_OK;
297 else {
298 LOG_ERROR("VSLLink setting speed failed (%d)", result);
299 return ERROR_JTAG_DEVICE_ERROR;
300 }
301
302 return ERROR_OK;
303 }
304
305 static int vsllink_khz(int khz, int *jtag_speed)
306 {
307 *jtag_speed = khz;
308
309 return ERROR_OK;
310 }
311
312 static int vsllink_speed_div(int jtag_speed, int *khz)
313 {
314 *khz = jtag_speed;
315
316 return ERROR_OK;
317 }
318
319 static int vsllink_init(void)
320 {
321 int check_cnt, to_tmp;
322 int result;
323 char version_str[100];
324
325 vsllink_usb_in_buffer = malloc(vsllink_buffer_size);
326 vsllink_usb_out_buffer = malloc(vsllink_buffer_size);
327 if ((vsllink_usb_in_buffer == NULL)
328 || (vsllink_usb_out_buffer == NULL)) {
329 LOG_ERROR("Not enough memory");
330 exit(-1);
331 }
332
333 vsllink_handle = vsllink_usb_open();
334 if (vsllink_handle == 0) {
335 LOG_ERROR("Can't find USB JTAG Interface!"\
336 "Please check connection and permissions.");
337 return ERROR_JTAG_INIT_FAILED;
338 }
339 LOG_DEBUG("vsllink found on %04X:%04X",
340 vsllink_usb_vid, vsllink_usb_pid);
341
342 to_tmp = VSLLINK_USB_TIMEOUT;
343 VSLLINK_USB_TIMEOUT = 100;
344 check_cnt = 0;
345 while (check_cnt < 5) {
346 vsllink_simple_command(VERSALOON_GET_INFO);
347 result = vsllink_usb_read(vsllink_handle);
348
349 if (result > 2) {
350 vsllink_usb_in_buffer[result] = 0;
351 vsllink_buffer_size = vsllink_usb_in_buffer[0]
352 + (vsllink_usb_in_buffer[1] << 8);
353 strncpy(version_str, (char *)vsllink_usb_in_buffer + 2,
354 sizeof(version_str));
355 LOG_INFO("%s", version_str);
356
357 /* free the pre-allocated memory */
358 free(vsllink_usb_in_buffer);
359 free(vsllink_usb_out_buffer);
360 vsllink_usb_in_buffer = NULL;
361 vsllink_usb_out_buffer = NULL;
362
363 /* alloc new memory */
364 vsllink_usb_in_buffer = malloc(vsllink_buffer_size);
365 vsllink_usb_out_buffer = malloc(vsllink_buffer_size);
366 if ((vsllink_usb_in_buffer == NULL) ||
367 (vsllink_usb_out_buffer == NULL)) {
368 LOG_ERROR("Not enough memory");
369 exit(-1);
370 } else
371 LOG_INFO("buffer size for USB is %d bytes",
372 vsllink_buffer_size);
373
374 /* alloc tms/tdi/tdo buffer */
375 tap_buffer_size = (vsllink_buffer_size - 3) / 2;
376 tms_buffer = (uint8_t *)malloc(tap_buffer_size);
377 tdi_buffer = (uint8_t *)malloc(tap_buffer_size);
378 tdo_buffer = (uint8_t *)malloc(tap_buffer_size);
379 if ((tms_buffer == NULL) || (tdi_buffer == NULL) ||
380 (tdo_buffer == NULL)) {
381 LOG_ERROR("Not enough memory");
382 exit(-1);
383 }
384 break;
385 }
386 vsllink_simple_command(VSLLINK_CMD_DISCONN);
387 check_cnt++;
388 }
389 if (check_cnt == 3) {
390 /* Fail to access Versaloon */
391 LOG_ERROR("VSLLink initial failed");
392 exit(-1);
393 }
394 VSLLINK_USB_TIMEOUT = to_tmp;
395
396 /* Some older firmware versions sometimes fail if the
397 * voltage isn't read first.
398 */
399 vsllink_simple_command(VERSALOON_GET_TVCC);
400 result = vsllink_usb_read(vsllink_handle);
401 if (result != 2)
402 LOG_WARNING("Fail to get target voltage");
403 else
404 LOG_INFO("Target runs at %d mV", vsllink_usb_in_buffer[0] +
405 (vsllink_usb_in_buffer[1] << 8));
406
407 /* connect to vsllink */
408 vsllink_usb_out_buffer[0] = VSLLINK_CMD_CONN;
409 vsllink_usb_out_buffer[1] = 1;
410 vsllink_usb_message(vsllink_handle, 2, 0);
411 if (vsllink_usb_read(vsllink_handle) > 2) {
412 strncpy(version_str, (char *)vsllink_usb_in_buffer + 2,
413 sizeof(version_str));
414 LOG_INFO("%s", version_str);
415 }
416
417 /* Set SRST and TRST to output, Set USR1 and USR2 to input */
418 vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORTDIR;
419 vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST
420 | JTAG_PINMSK_USR1 | JTAG_PINMSK_USR2;
421 vsllink_usb_out_buffer[2] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST;
422 if (vsllink_usb_write(vsllink_handle, 3) != 3) {
423 LOG_ERROR("VSLLink USB send data error");
424 exit(-1);
425 }
426
427 vsllink_reset(0, 0);
428
429 LOG_INFO("VSLLink Interface ready");
430
431 vsllink_tap_init();
432
433 return ERROR_OK;
434 }
435
436 static int vsllink_quit(void)
437 {
438 if ((vsllink_usb_in_buffer != NULL)
439 && (vsllink_usb_out_buffer != NULL)) {
440 // Set all pins to input
441 vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORTDIR;
442 vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST
443 | JTAG_PINMSK_USR1 | JTAG_PINMSK_USR2;
444 vsllink_usb_out_buffer[2] = 0;
445 if (vsllink_usb_write(vsllink_handle, 3) != 3) {
446 LOG_ERROR("VSLLink USB send data error");
447 exit(-1);
448 }
449
450 // disconnect
451 vsllink_simple_command(VSLLINK_CMD_DISCONN);
452 vsllink_usb_close(vsllink_handle);
453 vsllink_handle = NULL;
454 }
455
456 if (vsllink_usb_in_buffer != NULL) {
457 free(vsllink_usb_in_buffer);
458 vsllink_usb_in_buffer = NULL;
459 }
460 if (vsllink_usb_out_buffer != NULL) {
461 free(vsllink_usb_out_buffer);
462 vsllink_usb_out_buffer = NULL;
463 }
464
465 return ERROR_OK;
466 }
467
468 /***************************************************************************/
469 /* Queue command implementations */
470
471 static void vsllink_end_state(tap_state_t state)
472 {
473 if (tap_is_state_stable(state))
474 tap_set_end_state(state);
475 else {
476 LOG_ERROR("BUG: %i is not a valid end state", state);
477 exit(-1);
478 }
479 }
480
481 /* Goes to the end state. */
482 static void vsllink_state_move(void)
483 {
484 int i;
485 uint8_t tms_scan = tap_get_tms_path(tap_get_state(),
486 tap_get_end_state());
487 uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(),
488 tap_get_end_state());
489
490 for (i = 0; i < tms_scan_bits; i++)
491 vsllink_tap_append_step((tms_scan >> i) & 1, 0);
492
493 tap_set_state(tap_get_end_state());
494 }
495
496 static void vsllink_path_move(int num_states, tap_state_t *path)
497 {
498 for (int i = 0; i < num_states; i++) {
499 if (path[i] == tap_state_transition(tap_get_state(), false))
500 vsllink_tap_append_step(0, 0);
501 else if (path[i] == tap_state_transition(tap_get_state(), true))
502 vsllink_tap_append_step(1, 0);
503 else {
504 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
505 tap_state_name(tap_get_state()),
506 tap_state_name(path[i]));
507 exit(-1);
508 }
509
510 tap_set_state(path[i]);
511 }
512
513 tap_set_end_state(tap_get_state());
514 }
515
516 static void vsllink_stableclocks(int num_cycles, int tms)
517 {
518 while (num_cycles > 0) {
519 vsllink_tap_append_step(tms, 0);
520 num_cycles--;
521 }
522 }
523
524 static void vsllink_runtest(int num_cycles)
525 {
526 tap_state_t saved_end_state = tap_get_end_state();
527
528 if (tap_get_state() != TAP_IDLE) {
529 /* enter IDLE state */
530 vsllink_end_state(TAP_IDLE);
531 vsllink_state_move();
532 }
533
534 vsllink_stableclocks(num_cycles, 0);
535
536 // post-process
537 // set end_state
538 vsllink_end_state(saved_end_state);
539 if (tap_get_end_state() != tap_get_end_state())
540 vsllink_state_move();
541 }
542
543 static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
544 int scan_size, struct scan_command *command)
545 {
546 tap_state_t saved_end_state;
547
548 saved_end_state = tap_get_end_state();
549
550 /* Move to appropriate scan state */
551 vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
552
553 if (tap_get_state() != tap_get_end_state())
554 vsllink_state_move();
555 vsllink_end_state(saved_end_state);
556
557 /* Scan */
558 vsllink_tap_append_scan(scan_size, buffer, command);
559
560 /* Goto Pause and record position to insert tms:0 */
561 vsllink_tap_append_step(0, 0);
562 vsllink_tms_offset = tap_length;
563
564 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
565
566 if (tap_get_state() != tap_get_end_state())
567 vsllink_state_move();
568 }
569
570 static void vsllink_reset(int trst, int srst)
571 {
572 int result;
573
574 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
575
576 /* Signals are active low */
577 vsllink_usb_out_buffer[0] = VSLLINK_CMD_SET_PORT;
578 vsllink_usb_out_buffer[1] = JTAG_PINMSK_SRST | JTAG_PINMSK_TRST;
579 vsllink_usb_out_buffer[2] = 0;
580 if (srst == 0)
581 vsllink_usb_out_buffer[2] |= JTAG_PINMSK_SRST;
582 if (trst == 0)
583 vsllink_usb_out_buffer[2] |= JTAG_PINMSK_TRST;
584
585 result = vsllink_usb_write(vsllink_handle, 3);
586 if (result != 3)
587 LOG_ERROR("VSLLink command VSLLINK_CMD_SET_PORT failed (%d)",
588 result);
589 }
590
591 static void vsllink_simple_command(uint8_t command)
592 {
593 int result;
594
595 DEBUG_JTAG_IO("0x%02x", command);
596
597 vsllink_usb_out_buffer[0] = command;
598 result = vsllink_usb_write(vsllink_handle, 1);
599
600 if (result != 1)
601 LOG_ERROR("VSLLink command 0x%02x failed (%d)",
602 command, result);
603 }
604
605 COMMAND_HANDLER(vsllink_handle_mode_command)
606 {
607 if (CMD_ARGC != 1) {
608 LOG_ERROR("parameter error, "
609 "should be one parameter for mode");
610 return ERROR_FAIL;
611 }
612
613 return ERROR_OK;
614 }
615
616 COMMAND_HANDLER(vsllink_handle_usb_vid_command)
617 {
618 if (CMD_ARGC != 1) {
619 LOG_ERROR("parameter error, "
620 "should be one parameter for VID");
621 return ERROR_OK;
622 }
623
624 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], vsllink_usb_vid);
625 return ERROR_OK;
626 }
627
628 COMMAND_HANDLER(vsllink_handle_usb_pid_command)
629 {
630 if (CMD_ARGC != 1) {
631 LOG_ERROR("parameter error, "
632 "should be one parameter for PID");
633 return ERROR_OK;
634 }
635 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], vsllink_usb_pid);
636 return ERROR_OK;
637 }
638
639 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
640 {
641 if (CMD_ARGC != 1) {
642 LOG_ERROR("parameter error, "
643 "should be one parameter for BULKIN endpoint");
644 return ERROR_OK;
645 }
646
647 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], vsllink_usb_bulkin);
648
649 vsllink_usb_bulkin |= 0x80;
650
651 return ERROR_OK;
652 }
653
654 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
655 {
656 if (CMD_ARGC != 1) {
657 LOG_ERROR("parameter error, "
658 "should be one parameter for BULKOUT endpoint");
659 return ERROR_OK;
660 }
661
662 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], vsllink_usb_bulkout);
663
664 vsllink_usb_bulkout &= ~0x80;
665
666 return ERROR_OK;
667 }
668
669 COMMAND_HANDLER(vsllink_handle_usb_interface_command)
670 {
671 if (CMD_ARGC != 1) {
672 LOG_ERROR("parameter error, "
673 "should be one parameter for interface number");
674 return ERROR_OK;
675 }
676
677 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], vsllink_usb_interface);
678 return ERROR_OK;
679 }
680
681 /***************************************************************************/
682 /* VSLLink tap functions */
683
684 static void vsllink_tap_init(void)
685 {
686 tap_length = 0;
687 pending_scan_results_length = 0;
688 vsllink_tms_offset = 0;
689 }
690
691 static void vsllink_tap_ensure_pending(int scans)
692 {
693 int available_scans =
694 MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
695
696 if (scans > available_scans)
697 vsllink_tap_execute();
698 }
699
700 static void vsllink_tap_append_step(int tms, int tdi)
701 {
702 int index = tap_length / 8;
703
704 int bit_index = tap_length % 8;
705 uint8_t bit = 1 << bit_index;
706
707 if (tms)
708 tms_buffer[index] |= bit;
709 else
710 tms_buffer[index] &= ~bit;
711
712 if (tdi)
713 tdi_buffer[index] |= bit;
714 else
715 tdi_buffer[index] &= ~bit;
716
717 tap_length++;
718
719 if (tap_buffer_size * 8 <= tap_length)
720 vsllink_tap_execute();
721 }
722
723 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
724 struct scan_command *command)
725 {
726 struct pending_scan_result *pending_scan_result;
727 int len_tmp, len_all, i;
728
729 len_all = 0;
730 while (len_all < length) {
731 vsllink_tap_ensure_pending(1);
732 pending_scan_result =
733 &pending_scan_results_buffer[
734 pending_scan_results_length];
735
736 if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
737 /* Use all memory available
738 vsllink_tap_append_step will commit automatically */
739 len_tmp = tap_buffer_size * 8 - tap_length;
740 pending_scan_result->last = false;
741 } else {
742 len_tmp = length - len_all;
743 pending_scan_result->last = true;
744 }
745 pending_scan_result->src_offset = tap_length;
746 pending_scan_result->dest_offset = len_all;
747 pending_scan_result->length = len_tmp;
748 pending_scan_result->command = command;
749 pending_scan_result->buffer = buffer;
750 pending_scan_results_length++;
751
752 for (i = 0; i < len_tmp; i++) {
753 vsllink_tap_append_step(((len_all + i) < length-1
754 ? 0 : 1),
755 (buffer[(len_all + i)/8]
756 >> ((len_all + i)%8)) & 1);
757 }
758
759 len_all += len_tmp;
760 }
761 }
762
763 static int vsllink_tap_execute(void)
764 {
765 int byte_length;
766 int i;
767 int result;
768
769 if (tap_length <= 0)
770 return ERROR_OK;
771
772 /* Pad data so that tap_length is divisible by 8 */
773 if ((tap_length % 8) != 0) {
774 if (vsllink_tms_offset > 0) {
775 /* append tms:0 at vsllink_tms_offset,
776 * which is in Pause
777 */
778 int start_pos = DIV_ROUND_UP(tap_length, 8) - 1;
779 int end_pos = DIV_ROUND_UP(vsllink_tms_offset, 8) - 1;
780 int shift_cnt = (start_pos + 1) * 8 - tap_length;
781 uint8_t last_mask = ~(
782 (1 << (vsllink_tms_offset % 8)) - 1);
783
784 while (1) {
785 if (start_pos == end_pos) {
786 tms_buffer[start_pos] =
787 (tms_buffer[start_pos]
788 & ~last_mask)
789 | ((tms_buffer[start_pos]
790 & last_mask)
791 << shift_cnt);
792 tdi_buffer[start_pos] =
793 (tdi_buffer[start_pos]
794 & ~last_mask)
795 |
796 ((tdi_buffer[start_pos]
797 & last_mask)
798 << shift_cnt);
799 break;
800 } else if (start_pos == (end_pos + 1)) {
801 tms_buffer[start_pos] =
802 (tms_buffer[start_pos]
803 << shift_cnt) |
804 ((tms_buffer[start_pos - 1]
805 & last_mask)
806 >> (8 - shift_cnt));
807 tdi_buffer[start_pos] =
808 (tdi_buffer[start_pos]
809 << shift_cnt) |
810 ((tdi_buffer[start_pos - 1]
811 & last_mask)
812 >> (8 - shift_cnt));
813 } else {
814 tms_buffer[start_pos] =
815 (tms_buffer[start_pos]
816 << shift_cnt) |
817 (tms_buffer[start_pos - 1]
818 >> (8 - shift_cnt));
819 tdi_buffer[start_pos] =
820 (tdi_buffer[start_pos]
821 << shift_cnt) |
822 (tdi_buffer[start_pos - 1]
823 >> (8 - shift_cnt));
824 }
825 start_pos--;
826 }
827 tap_length = DIV_ROUND_UP(tap_length, 8) * 8;
828 } else {
829 /* append data at last */
830 while ((tap_length % 8) != 0) {
831 vsllink_tap_append_step(
832 (tap_get_state() == TAP_RESET)
833 ? 1 : 0, 0);
834 }
835 }
836 }
837 byte_length = tap_length / 8;
838
839 vsllink_usb_out_buffer[0] = VSLLINK_CMD_HW_JTAGRAWCMD;
840 vsllink_usb_out_buffer[1] = ((byte_length * 2 + 3) >> 0) & 0xff;
841 vsllink_usb_out_buffer[2] = ((byte_length * 2 + 3) >> 8) & 0xff;
842
843 memcpy(&vsllink_usb_out_buffer[3], tdi_buffer, byte_length);
844 memcpy(&vsllink_usb_out_buffer[3 + byte_length], tms_buffer,
845 byte_length);
846
847 result = vsllink_usb_message(vsllink_handle, 3 + 2 * byte_length,
848 byte_length);
849
850 if (result == byte_length) {
851 for (i = 0; i < pending_scan_results_length; i++) {
852 struct pending_scan_result *pending_scan_result =
853 &pending_scan_results_buffer[i];
854 uint8_t *buffer = pending_scan_result->buffer;
855 int length = pending_scan_result->length;
856 int src_first = pending_scan_result->src_offset;
857 int dest_first = pending_scan_result->dest_offset;
858 bool last = pending_scan_result->last;
859
860 struct scan_command *command;
861
862 command = pending_scan_result->command;
863 buf_set_buf(vsllink_usb_in_buffer, src_first, buffer,
864 dest_first, length);
865
866 DEBUG_JTAG_IO("JTAG scan read(%d bits, from %d bits):",
867 length, dest_first);
868 #ifdef _DEBUG_JTAG_IO_
869 vsllink_debug_buffer(buffer + dest_first / 8,
870 DIV_ROUND_UP(length, 7));
871 #endif
872
873 if (last) {
874 if (jtag_read_buffer(buffer, command)
875 != ERROR_OK) {
876 vsllink_tap_init();
877 return ERROR_JTAG_QUEUE_FAILED;
878 }
879
880 if (pending_scan_result->buffer != NULL)
881 free(pending_scan_result->buffer);
882 }
883 }
884 } else {
885 LOG_ERROR("vsllink_tap_execute, wrong result %d, expected %d",
886 result, byte_length);
887 return ERROR_JTAG_QUEUE_FAILED;
888 }
889
890 vsllink_tap_init();
891
892 return ERROR_OK;
893 }
894
895 /*****************************************************************************/
896 /* VSLLink USB low-level functions */
897
898 static struct vsllink *vsllink_usb_open(void)
899 {
900 usb_init();
901
902 const uint16_t vids[] = { vsllink_usb_vid, 0 };
903 const uint16_t pids[] = { vsllink_usb_pid, 0 };
904 struct usb_dev_handle *dev;
905 if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
906 return NULL;
907
908 /* usb_set_configuration required under win32 */
909 struct usb_device *udev = usb_device(dev);
910 int ret = usb_set_configuration(dev,
911 udev->config[0].bConfigurationValue);
912 if (ret != 0) {
913 LOG_ERROR("fail to set configuration to %d (error %d)."
914 "Not enough permissions for the device?",
915 udev->config[0].bConfigurationValue, ret);
916 return NULL;
917 }
918 ret = usb_claim_interface(dev, vsllink_usb_interface);
919 if (ret != 0) {
920 LOG_ERROR("fail to claim interface %d, %d returned",
921 vsllink_usb_interface, ret);
922 return NULL;
923 }
924 #if 0
925 /*
926 * This makes problems under Mac OS X. And is not needed
927 * under Windows. Hopefully this will not break a linux build
928 */
929 usb_set_altinterface(dev, 0);
930 #endif
931
932 struct vsllink *result = malloc(sizeof(struct vsllink));
933 result->usb_handle = dev;
934 return result;
935 }
936
937 static void vsllink_usb_close(struct vsllink *vsllink)
938 {
939 int ret;
940
941 ret = usb_release_interface(vsllink->usb_handle,
942 vsllink_usb_interface);
943 if (ret != 0) {
944 LOG_ERROR("fail to release interface %d, %d returned",
945 vsllink_usb_interface, ret);
946 exit(-1);
947 }
948
949 ret = usb_close(vsllink->usb_handle);
950 if (ret != 0) {
951 LOG_ERROR("fail to close usb, %d returned", ret);
952 exit(-1);
953 }
954
955 free(vsllink);
956 }
957
958 /* Send a message and receive the reply. */
959 static int vsllink_usb_message(struct vsllink *vsllink, int out_length,
960 int in_length)
961 {
962 int result;
963
964 result = vsllink_usb_write(vsllink, out_length);
965 if (result == out_length) {
966 if (in_length > 0) {
967 result = vsllink_usb_read(vsllink);
968 if (result == in_length)
969 return result;
970 else {
971 LOG_ERROR("usb_bulk_read failed "
972 "(requested=%d, result=%d)",
973 in_length, result);
974 return -1;
975 }
976 }
977 return 0;
978 } else {
979 LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)",
980 out_length, result);
981 return -1;
982 }
983 }
984
985 /* Write data from out_buffer to USB. */
986 static int vsllink_usb_write(struct vsllink *vsllink, int out_length)
987 {
988 int result;
989
990 if (out_length > vsllink_buffer_size) {
991 LOG_ERROR("vsllink_write illegal out_length=%d (max=%d)",
992 out_length, vsllink_buffer_size);
993 return -1;
994 }
995
996 result = usb_bulk_write(vsllink->usb_handle, vsllink_usb_bulkout,
997 (char *)vsllink_usb_out_buffer, out_length,
998 VSLLINK_USB_TIMEOUT);
999
1000 DEBUG_JTAG_IO("vsllink_usb_write, out_length = %d, result = %d",
1001 out_length, result);
1002
1003 #ifdef _DEBUG_USB_COMMS_
1004 LOG_DEBUG("USB out:");
1005 vsllink_debug_buffer(vsllink_usb_out_buffer, out_length);
1006 #endif
1007
1008 #ifdef _VSLLINK_IN_DEBUG_MODE_
1009 usleep(100000);
1010 #endif
1011
1012 return result;
1013 }
1014
1015 /* Read data from USB into in_buffer. */
1016 static int vsllink_usb_read(struct vsllink *vsllink)
1017 {
1018 int result = usb_bulk_read(vsllink->usb_handle, vsllink_usb_bulkin,
1019 (char *)vsllink_usb_in_buffer, vsllink_buffer_size,
1020 VSLLINK_USB_TIMEOUT);
1021
1022 DEBUG_JTAG_IO("vsllink_usb_read, result = %d", result);
1023
1024 #ifdef _DEBUG_USB_COMMS_
1025 LOG_DEBUG("USB in:");
1026 vsllink_debug_buffer(vsllink_usb_in_buffer, result);
1027 #endif
1028 return result;
1029 }
1030
1031 #define BYTES_PER_LINE 16
1032
1033 #if defined _DEBUG_USB_COMMS_ || defined _DEBUG_JTAG_IO_
1034 static void vsllink_debug_buffer(uint8_t *buffer, int length)
1035 {
1036 char line[81];
1037 char s[4];
1038 int i;
1039 int j;
1040
1041 for (i = 0; i < length; i += BYTES_PER_LINE) {
1042 snprintf(line, 5, "%04x", i);
1043 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
1044 snprintf(s, 4, " %02x", buffer[j]);
1045 strcat(line, s);
1046 }
1047 LOG_DEBUG("%s", line);
1048 }
1049 }
1050 #endif /* _DEBUG_USB_COMMS_ || _DEBUG_JTAG_IO_ */
1051
1052 static const struct command_registration vsllink_command_handlers[] = {
1053 {
1054 .name = "vsllink_usb_vid",
1055 .handler = &vsllink_handle_usb_vid_command,
1056 .mode = COMMAND_CONFIG,
1057 },
1058 {
1059 .name = "vsllink_usb_pid",
1060 .handler = &vsllink_handle_usb_pid_command,
1061 .mode = COMMAND_CONFIG,
1062 },
1063 {
1064 .name = "vsllink_usb_bulkin",
1065 .handler = &vsllink_handle_usb_bulkin_command,
1066 .mode = COMMAND_CONFIG,
1067 },
1068 {
1069 .name = "vsllink_usb_bulkout",
1070 .handler = &vsllink_handle_usb_bulkout_command,
1071 .mode = COMMAND_CONFIG,
1072 },
1073 {
1074 .name = "vsllink_usb_interface",
1075 .handler = &vsllink_handle_usb_interface_command,
1076 .mode = COMMAND_CONFIG,
1077 },
1078 {
1079 .name = "vsllink_mode",
1080 .handler = &vsllink_handle_mode_command,
1081 .mode = COMMAND_CONFIG,
1082 },
1083 COMMAND_REGISTRATION_DONE
1084 };
1085
1086 struct jtag_interface vsllink_interface = {
1087 .name = "vsllink",
1088 .commands = vsllink_command_handlers,
1089
1090 .init = vsllink_init,
1091 .quit = vsllink_quit,
1092 .khz = vsllink_khz,
1093 .speed = vsllink_speed,
1094 .speed_div = vsllink_speed_div,
1095 .execute_queue = vsllink_execute_queue,
1096 };

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)