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

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)