swd: remove unused API frequency()
[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, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18 /* Versaloon is a programming tool for multiple MCUs.
19 * It's distributed under GPLv3.
20 * You can find it at http://www.Versaloon.com/.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <jtag/interface.h>
28 #include <jtag/commands.h>
29 #include <jtag/swd.h>
30 #include <libusb.h>
31
32 #include "versaloon/versaloon_include.h"
33 #include "versaloon/versaloon.h"
34
35 static int vsllink_tms_offset;
36
37 struct pending_scan_result {
38 int src_offset;
39 int dest_offset;
40 int length; /* Number of bits to read */
41 struct scan_command *command; /* Corresponding scan command */
42 uint8_t *ack;
43 uint8_t *buffer;
44 bool last; /* indicate the last scan pending */
45 };
46
47 #define MAX_PENDING_SCAN_RESULTS 256
48
49 static int pending_scan_results_length;
50 static struct pending_scan_result
51 pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];
52
53 /* Queue command functions */
54 static void vsllink_end_state(tap_state_t state);
55 static void vsllink_state_move(void);
56 static void vsllink_path_move(int num_states, tap_state_t *path);
57 static void vsllink_tms(int num_bits, const uint8_t *bits);
58 static void vsllink_runtest(int num_cycles);
59 static void vsllink_stableclocks(int num_cycles, int tms);
60 static void vsllink_scan(bool ir_scan, enum scan_type type,
61 uint8_t *buffer, int scan_size, struct scan_command *command);
62 static void vsllink_reset(int trst, int srst);
63
64 /* VSLLink tap buffer functions */
65 static void vsllink_tap_append_step(int tms, int tdi);
66 static void vsllink_tap_init(void);
67 static int vsllink_tap_execute(void);
68 static void vsllink_tap_ensure_pending(int scans);
69 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
70 struct scan_command *command);
71
72 /* VSLLink SWD functions */
73 static int_least32_t vsllink_swd_frequency(int_least32_t hz);
74 static int vsllink_swd_switch_seq(enum swd_special_seq seq);
75
76 /* VSLLink lowlevel functions */
77 struct vsllink {
78 struct libusb_context *libusb_ctx;
79 struct libusb_device_handle *usb_device_handle;
80 };
81
82 static int vsllink_usb_open(struct vsllink *vsllink);
83 static void vsllink_usb_close(struct vsllink *vsllink);
84
85 static void vsllink_debug_buffer(uint8_t *buffer, int length);
86
87 static int tap_length;
88 static int tap_buffer_size;
89 static uint8_t *tms_buffer;
90 static uint8_t *tdi_buffer;
91 static uint8_t *tdo_buffer;
92
93 static bool swd_mode;
94
95 static struct vsllink *vsllink_handle;
96
97 static int vsllink_execute_queue(void)
98 {
99 struct jtag_command *cmd = jtag_command_queue;
100 int scan_size;
101 enum scan_type type;
102 uint8_t *buffer;
103
104 LOG_DEBUG_IO("-------------------------------------"
105 " vsllink "
106 "-------------------------------------");
107
108 while (cmd != NULL) {
109 switch (cmd->type) {
110 case JTAG_RUNTEST:
111 LOG_DEBUG_IO("runtest %i cycles, end in %s",
112 cmd->cmd.runtest->num_cycles,
113 tap_state_name(cmd->cmd.runtest->end_state));
114
115 vsllink_end_state(cmd->cmd.runtest->end_state);
116 vsllink_runtest(cmd->cmd.runtest->num_cycles);
117 break;
118
119 case JTAG_TLR_RESET:
120 LOG_DEBUG_IO("statemove end in %s",
121 tap_state_name(cmd->cmd.statemove->end_state));
122
123 vsllink_end_state(cmd->cmd.statemove->end_state);
124 vsllink_state_move();
125 break;
126
127 case JTAG_PATHMOVE:
128 LOG_DEBUG_IO("pathmove: %i states, end in %s",
129 cmd->cmd.pathmove->num_states,
130 tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
131
132 vsllink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
133 break;
134
135 case JTAG_SCAN:
136 LOG_DEBUG_IO("JTAG Scan...");
137
138 vsllink_end_state(cmd->cmd.scan->end_state);
139
140 scan_size = jtag_build_buffer(
141 cmd->cmd.scan, &buffer);
142
143 if (cmd->cmd.scan->ir_scan)
144 LOG_DEBUG_IO(
145 "JTAG Scan write IR(%d bits), "
146 "end in %s:",
147 scan_size,
148 tap_state_name(cmd->cmd.scan->end_state));
149
150 else
151 LOG_DEBUG_IO(
152 "JTAG Scan write DR(%d bits), "
153 "end in %s:",
154 scan_size,
155 tap_state_name(cmd->cmd.scan->end_state));
156
157 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))
158 vsllink_debug_buffer(buffer, DIV_ROUND_UP(scan_size, 8));
159
160 type = jtag_scan_type(cmd->cmd.scan);
161
162 vsllink_scan(cmd->cmd.scan->ir_scan,
163 type, buffer, scan_size,
164 cmd->cmd.scan);
165 break;
166
167 case JTAG_RESET:
168 LOG_DEBUG_IO("reset trst: %i srst %i",
169 cmd->cmd.reset->trst,
170 cmd->cmd.reset->srst);
171
172 vsllink_tap_execute();
173
174 if (cmd->cmd.reset->trst == 1)
175 tap_set_state(TAP_RESET);
176
177 vsllink_reset(cmd->cmd.reset->trst,
178 cmd->cmd.reset->srst);
179 break;
180
181 case JTAG_SLEEP:
182 LOG_DEBUG_IO("sleep %i", cmd->cmd.sleep->us);
183 vsllink_tap_execute();
184 jtag_sleep(cmd->cmd.sleep->us);
185 break;
186
187 case JTAG_STABLECLOCKS:
188 LOG_DEBUG_IO("add %d clocks",
189 cmd->cmd.stableclocks->num_cycles);
190
191 switch (tap_get_state()) {
192 case TAP_RESET:
193 /* tms must be '1' to stay
194 * n TAP_RESET mode
195 */
196 scan_size = 1;
197 break;
198 case TAP_DRSHIFT:
199 case TAP_IDLE:
200 case TAP_DRPAUSE:
201 case TAP_IRSHIFT:
202 case TAP_IRPAUSE:
203 /* else, tms should be '0' */
204 scan_size = 0;
205 break;
206 /* above stable states are OK */
207 default:
208 LOG_ERROR("jtag_add_clocks() "
209 "in non-stable state \"%s\"",
210 tap_state_name(tap_get_state())
211 );
212 exit(-1);
213 }
214 vsllink_stableclocks(cmd->cmd.stableclocks->num_cycles, scan_size);
215 break;
216
217 case JTAG_TMS:
218 LOG_DEBUG_IO("add %d jtag tms",
219 cmd->cmd.tms->num_bits);
220
221 vsllink_tms(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
222 break;
223
224 default:
225 LOG_ERROR("BUG: unknown JTAG command type "
226 "encountered: %d", cmd->type);
227 exit(-1);
228 }
229 cmd = cmd->next;
230 }
231
232 return vsllink_tap_execute();
233 }
234
235 static int vsllink_speed(int speed)
236 {
237 if (swd_mode) {
238 vsllink_swd_frequency(speed * 1000);
239 return ERROR_OK;
240 }
241
242 versaloon_interface.adaptors.jtag_raw.config(0, (uint16_t)speed);
243 return versaloon_interface.adaptors.peripheral_commit();
244 }
245
246 static int vsllink_khz(int khz, int *jtag_speed)
247 {
248 *jtag_speed = khz;
249
250 return ERROR_OK;
251 }
252
253 static int vsllink_speed_div(int jtag_speed, int *khz)
254 {
255 *khz = jtag_speed;
256
257 return ERROR_OK;
258 }
259
260 static void vsllink_free_buffer(void)
261 {
262 if (tdi_buffer != NULL) {
263 free(tdi_buffer);
264 tdi_buffer = NULL;
265 }
266 if (tdo_buffer != NULL) {
267 free(tdo_buffer);
268 tdo_buffer = NULL;
269 }
270 if (tms_buffer != NULL) {
271 free(tms_buffer);
272 tms_buffer = NULL;
273 }
274 }
275
276 static int vsllink_quit(void)
277 {
278 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
279 0, 0, GPIO_SRST | GPIO_TRST);
280 versaloon_interface.adaptors.gpio.fini(0);
281
282 if (swd_mode)
283 versaloon_interface.adaptors.swd.fini(0);
284 else
285 versaloon_interface.adaptors.jtag_raw.fini(0);
286
287 versaloon_interface.adaptors.peripheral_commit();
288 versaloon_interface.fini();
289
290 vsllink_free_buffer();
291 vsllink_usb_close(vsllink_handle);
292
293 free(vsllink_handle);
294
295 return ERROR_OK;
296 }
297
298 static int vsllink_interface_init(void)
299 {
300 vsllink_handle = malloc(sizeof(struct vsllink));
301 if (NULL == vsllink_handle) {
302 LOG_ERROR("unable to allocate memory");
303 return ERROR_FAIL;
304 }
305
306 libusb_init(&vsllink_handle->libusb_ctx);
307
308 if (ERROR_OK != vsllink_usb_open(vsllink_handle)) {
309 LOG_ERROR("Can't find USB JTAG Interface!" \
310 "Please check connection and permissions.");
311 return ERROR_JTAG_INIT_FAILED;
312 }
313 LOG_DEBUG("vsllink found on %04X:%04X",
314 versaloon_interface.usb_setting.vid,
315 versaloon_interface.usb_setting.pid);
316 versaloon_usb_device_handle = vsllink_handle->usb_device_handle;
317
318 if (ERROR_OK != versaloon_interface.init())
319 return ERROR_FAIL;
320 if (versaloon_interface.usb_setting.buf_size < 32) {
321 versaloon_interface.fini();
322 return ERROR_FAIL;
323 }
324
325 return ERROR_OK;
326 }
327
328 static int vsllink_init(void)
329 {
330 int retval = vsllink_interface_init();
331 if (ERROR_OK != retval)
332 return retval;
333
334 versaloon_interface.adaptors.gpio.init(0);
335 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST,
336 GPIO_SRST);
337 versaloon_interface.adaptors.delay.delayms(100);
338 versaloon_interface.adaptors.peripheral_commit();
339
340 if (swd_mode) {
341 versaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0,
342 GPIO_TRST, GPIO_TRST);
343 versaloon_interface.adaptors.swd.init(0);
344 vsllink_swd_frequency(jtag_get_speed_khz() * 1000);
345 vsllink_swd_switch_seq(JTAG_TO_SWD);
346
347 } else {
348 /* malloc buffer size for tap */
349 tap_buffer_size = versaloon_interface.usb_setting.buf_size / 2 - 32;
350 vsllink_free_buffer();
351 tdi_buffer = malloc(tap_buffer_size);
352 tdo_buffer = malloc(tap_buffer_size);
353 tms_buffer = malloc(tap_buffer_size);
354 if ((NULL == tdi_buffer) || (NULL == tdo_buffer) || (NULL == tms_buffer)) {
355 vsllink_quit();
356 return ERROR_FAIL;
357 }
358
359 versaloon_interface.adaptors.jtag_raw.init(0);
360 versaloon_interface.adaptors.jtag_raw.config(0, jtag_get_speed_khz());
361 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,
362 GPIO_TRST, GPIO_SRST, GPIO_SRST);
363 }
364
365 if (ERROR_OK != versaloon_interface.adaptors.peripheral_commit())
366 return ERROR_FAIL;
367
368 vsllink_reset(0, 0);
369 vsllink_tap_init();
370 return ERROR_OK;
371 }
372
373 /**************************************************************************
374 * Queue command implementations */
375
376 static void vsllink_end_state(tap_state_t state)
377 {
378 if (tap_is_state_stable(state))
379 tap_set_end_state(state);
380 else {
381 LOG_ERROR("BUG: %i is not a valid end state", state);
382 exit(-1);
383 }
384 }
385
386 /* Goes to the end state. */
387 static void vsllink_state_move(void)
388 {
389 int i;
390 uint8_t tms_scan = tap_get_tms_path(tap_get_state(),
391 tap_get_end_state());
392 uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(),
393 tap_get_end_state());
394
395 for (i = 0; i < tms_scan_bits; i++)
396 vsllink_tap_append_step((tms_scan >> i) & 1, 0);
397
398 tap_set_state(tap_get_end_state());
399 }
400
401 static void vsllink_path_move(int num_states, tap_state_t *path)
402 {
403 for (int i = 0; i < num_states; i++) {
404 if (path[i] == tap_state_transition(tap_get_state(), false))
405 vsllink_tap_append_step(0, 0);
406 else if (path[i] == tap_state_transition(tap_get_state(), true))
407 vsllink_tap_append_step(1, 0);
408 else {
409 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
410 tap_state_name(tap_get_state()),
411 tap_state_name(path[i]));
412 exit(-1);
413 }
414
415 tap_set_state(path[i]);
416 }
417
418 tap_set_end_state(tap_get_state());
419 }
420
421 static void vsllink_tms(int num_bits, const uint8_t *bits)
422 {
423 for (int i = 0; i < num_bits; i++)
424 vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0);
425 }
426
427 static void vsllink_stableclocks(int num_cycles, int tms)
428 {
429 while (num_cycles > 0) {
430 vsllink_tap_append_step(tms, 0);
431 num_cycles--;
432 }
433 }
434
435 static void vsllink_runtest(int num_cycles)
436 {
437 tap_state_t saved_end_state = tap_get_end_state();
438
439 if (tap_get_state() != TAP_IDLE) {
440 /* enter IDLE state */
441 vsllink_end_state(TAP_IDLE);
442 vsllink_state_move();
443 }
444
445 vsllink_stableclocks(num_cycles, 0);
446
447 /* post-process */
448 /* set end_state */
449 vsllink_end_state(saved_end_state);
450 if (tap_get_end_state() != tap_get_end_state())
451 vsllink_state_move();
452 }
453
454 static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
455 int scan_size, struct scan_command *command)
456 {
457 tap_state_t saved_end_state;
458
459 saved_end_state = tap_get_end_state();
460
461 /* Move to appropriate scan state */
462 vsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);
463
464 if (tap_get_state() != tap_get_end_state())
465 vsllink_state_move();
466 vsllink_end_state(saved_end_state);
467
468 /* Scan */
469 vsllink_tap_append_scan(scan_size, buffer, command);
470
471 /* Goto Pause and record position to insert tms:0 */
472 vsllink_tap_append_step(0, 0);
473 vsllink_tms_offset = tap_length;
474
475 tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
476
477 if (tap_get_state() != tap_get_end_state())
478 vsllink_state_move();
479 }
480
481 static void vsllink_reset(int trst, int srst)
482 {
483 LOG_DEBUG("trst: %i, srst: %i", trst, srst);
484
485 if (!srst)
486 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, GPIO_SRST);
487 else
488 versaloon_interface.adaptors.gpio.config(0, GPIO_SRST, GPIO_SRST, 0, 0);
489
490 if (!swd_mode) {
491 if (!trst)
492 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST);
493 else
494 versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);
495 }
496
497 versaloon_interface.adaptors.peripheral_commit();
498 }
499
500 COMMAND_HANDLER(vsllink_handle_usb_vid_command)
501 {
502 if (CMD_ARGC != 1)
503 return ERROR_COMMAND_SYNTAX_ERROR;
504
505 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
506 versaloon_interface.usb_setting.vid);
507 return ERROR_OK;
508 }
509
510 COMMAND_HANDLER(vsllink_handle_usb_pid_command)
511 {
512 if (CMD_ARGC != 1)
513 return ERROR_COMMAND_SYNTAX_ERROR;
514 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],
515 versaloon_interface.usb_setting.pid);
516 return ERROR_OK;
517 }
518
519 COMMAND_HANDLER(vsllink_handle_usb_serial_command)
520 {
521 if (CMD_ARGC > 1)
522 return ERROR_COMMAND_SYNTAX_ERROR;
523
524 free(versaloon_interface.usb_setting.serialstring);
525
526 if (CMD_ARGC == 1)
527 versaloon_interface.usb_setting.serialstring = strdup(CMD_ARGV[0]);
528 else
529 versaloon_interface.usb_setting.serialstring = NULL;
530
531 return ERROR_OK;
532 }
533
534 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command)
535 {
536 if (CMD_ARGC != 1)
537 return ERROR_COMMAND_SYNTAX_ERROR;
538
539 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
540 versaloon_interface.usb_setting.ep_in);
541
542 versaloon_interface.usb_setting.ep_in |= 0x80;
543
544 return ERROR_OK;
545 }
546
547 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command)
548 {
549 if (CMD_ARGC != 1)
550 return ERROR_COMMAND_SYNTAX_ERROR;
551
552 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
553 versaloon_interface.usb_setting.ep_out);
554
555 versaloon_interface.usb_setting.ep_out &= ~0x80;
556
557 return ERROR_OK;
558 }
559
560 COMMAND_HANDLER(vsllink_handle_usb_interface_command)
561 {
562 if (CMD_ARGC != 1)
563 return ERROR_COMMAND_SYNTAX_ERROR;
564
565 COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],
566 versaloon_interface.usb_setting.interface);
567 return ERROR_OK;
568 }
569
570 /**************************************************************************
571 * VSLLink tap functions */
572
573 static void vsllink_tap_init(void)
574 {
575 tap_length = 0;
576 pending_scan_results_length = 0;
577 vsllink_tms_offset = 0;
578 }
579
580 static void vsllink_tap_ensure_pending(int scans)
581 {
582 int available_scans =
583 MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
584
585 if (scans > available_scans)
586 vsllink_tap_execute();
587 }
588
589 static void vsllink_tap_append_step(int tms, int tdi)
590 {
591 int index_var = tap_length / 8;
592
593 int bit_index = tap_length % 8;
594 uint8_t bit = 1 << bit_index;
595
596 if (tms)
597 tms_buffer[index_var] |= bit;
598 else
599 tms_buffer[index_var] &= ~bit;
600
601 if (tdi)
602 tdi_buffer[index_var] |= bit;
603 else
604 tdi_buffer[index_var] &= ~bit;
605
606 tap_length++;
607
608 if (tap_buffer_size * 8 <= tap_length)
609 vsllink_tap_execute();
610 }
611
612 static void vsllink_tap_append_scan(int length, uint8_t *buffer,
613 struct scan_command *command)
614 {
615 struct pending_scan_result *pending_scan_result;
616 int len_tmp, len_all, i;
617
618 len_all = 0;
619 while (len_all < length) {
620 vsllink_tap_ensure_pending(1);
621 pending_scan_result =
622 &pending_scan_results_buffer[
623 pending_scan_results_length];
624
625 if ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {
626 /* Use all memory available
627 vsllink_tap_append_step will commit automatically */
628 len_tmp = tap_buffer_size * 8 - tap_length;
629 pending_scan_result->last = false;
630 } else {
631 len_tmp = length - len_all;
632 pending_scan_result->last = true;
633 }
634 pending_scan_result->src_offset = tap_length;
635 pending_scan_result->dest_offset = len_all;
636 pending_scan_result->length = len_tmp;
637 pending_scan_result->command = command;
638 pending_scan_result->buffer = buffer;
639 pending_scan_results_length++;
640
641 for (i = 0; i < len_tmp; i++) {
642 vsllink_tap_append_step(((len_all + i) < length-1
643 ? 0 : 1),
644 (buffer[(len_all + i)/8]
645 >> ((len_all + i)%8)) & 1);
646 }
647
648 len_all += len_tmp;
649 }
650 }
651
652 static int vsllink_jtag_execute(void)
653 {
654 int i;
655 int result;
656
657 if (tap_length <= 0)
658 return ERROR_OK;
659
660 versaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer,
661 tdo_buffer, tap_length);
662
663 result = versaloon_interface.adaptors.peripheral_commit();
664
665 if (result == ERROR_OK) {
666 for (i = 0; i < pending_scan_results_length; i++) {
667 struct pending_scan_result *pending_scan_result =
668 &pending_scan_results_buffer[i];
669 uint8_t *buffer = pending_scan_result->buffer;
670 int length = pending_scan_result->length;
671 int src_first = pending_scan_result->src_offset;
672 int dest_first = pending_scan_result->dest_offset;
673 bool last = pending_scan_result->last;
674
675 struct scan_command *command;
676
677 command = pending_scan_result->command;
678 buf_set_buf(tdo_buffer, src_first, buffer, dest_first, length);
679
680 LOG_DEBUG_IO(
681 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
682 length, src_first, dest_first);
683 if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))
684 vsllink_debug_buffer(buffer + dest_first / 8, DIV_ROUND_UP(length, 7));
685
686 if (last) {
687 if (jtag_read_buffer(buffer, command)
688 != ERROR_OK) {
689 vsllink_tap_init();
690 return ERROR_JTAG_QUEUE_FAILED;
691 }
692
693 if (pending_scan_result->buffer != NULL)
694 free(pending_scan_result->buffer);
695 }
696 }
697 } else {
698 LOG_ERROR("vsllink_jtag_execute failure");
699 return ERROR_JTAG_QUEUE_FAILED;
700 }
701
702 vsllink_tap_init();
703
704 return ERROR_OK;
705 }
706
707 static int vsllink_tap_execute(void)
708 {
709 if (swd_mode)
710 return ERROR_OK;
711
712 return vsllink_jtag_execute();
713 }
714
715 static int vsllink_swd_init(void)
716 {
717 LOG_INFO("VSLLink SWD mode enabled");
718 swd_mode = true;
719
720 return ERROR_OK;
721 }
722
723 static int_least32_t vsllink_swd_frequency(int_least32_t hz)
724 {
725 const int_least32_t delay2hz[] = {
726 1850000, 235000, 130000, 102000, 85000, 72000
727 };
728
729 if (hz > 0) {
730 uint16_t delay = UINT16_MAX;
731
732 for (uint16_t i = 0; i < ARRAY_SIZE(delay2hz); i++) {
733 if (hz >= delay2hz[i]) {
734 hz = delay2hz[i];
735 delay = i;
736 break;
737 }
738 }
739
740 if (delay == UINT16_MAX)
741 delay = (500000 / hz) - 1;
742
743 /* Calculate retry count after a WAIT response. This will give
744 * a retry timeout at about ~250 ms. 54 is the number of bits
745 * found in a transaction. */
746 uint16_t retry_count = 250 * hz / 1000 / 54;
747
748 LOG_DEBUG("SWD delay: %d, retry count: %d", delay, retry_count);
749
750 versaloon_interface.adaptors.swd.config(0, 2, retry_count, delay);
751 }
752
753 return hz;
754 }
755
756 static int vsllink_swd_switch_seq(enum swd_special_seq seq)
757 {
758 switch (seq) {
759 case LINE_RESET:
760 LOG_DEBUG("SWD line reset");
761 versaloon_interface.adaptors.swd.seqout(0, swd_seq_line_reset,
762 swd_seq_line_reset_len);
763 break;
764 case JTAG_TO_SWD:
765 LOG_DEBUG("JTAG-to-SWD");
766 versaloon_interface.adaptors.swd.seqout(0, swd_seq_jtag_to_swd,
767 swd_seq_jtag_to_swd_len);
768 break;
769 case SWD_TO_JTAG:
770 LOG_DEBUG("SWD-to-JTAG");
771 versaloon_interface.adaptors.swd.seqout(0, swd_seq_swd_to_jtag,
772 swd_seq_swd_to_jtag_len);
773 break;
774 default:
775 LOG_ERROR("Sequence %d not supported", seq);
776 return ERROR_FAIL;
777 }
778
779 return ERROR_OK;
780 }
781
782 static void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
783 {
784 versaloon_interface.adaptors.swd.transact(0, cmd, value, NULL);
785 }
786
787 static void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
788 {
789 versaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL);
790 }
791
792 static int vsllink_swd_run_queue(void)
793 {
794 return versaloon_interface.adaptors.peripheral_commit();
795 }
796
797 /****************************************************************************
798 * VSLLink USB low-level functions */
799
800 static int vsllink_check_usb_strings(
801 struct libusb_device_handle *usb_device_handle,
802 struct libusb_device_descriptor *usb_desc)
803 {
804 char desc_string[256];
805 int retval;
806
807 if (NULL != versaloon_interface.usb_setting.serialstring) {
808 retval = libusb_get_string_descriptor_ascii(usb_device_handle,
809 usb_desc->iSerialNumber, (unsigned char *)desc_string,
810 sizeof(desc_string));
811 if (retval < 0)
812 return ERROR_FAIL;
813
814 if (strncmp(desc_string, versaloon_interface.usb_setting.serialstring,
815 sizeof(desc_string)))
816 return ERROR_FAIL;
817 }
818
819 retval = libusb_get_string_descriptor_ascii(usb_device_handle,
820 usb_desc->iProduct, (unsigned char *)desc_string,
821 sizeof(desc_string));
822 if (retval < 0)
823 return ERROR_FAIL;
824
825 if (strstr(desc_string, "Versaloon") == NULL)
826 return ERROR_FAIL;
827
828 return ERROR_OK;
829 }
830
831 static int vsllink_usb_open(struct vsllink *vsllink)
832 {
833 ssize_t num_devices, i;
834 libusb_device **usb_devices;
835 struct libusb_device_descriptor usb_desc;
836 struct libusb_device_handle *usb_device_handle;
837 int retval;
838
839 num_devices = libusb_get_device_list(vsllink->libusb_ctx, &usb_devices);
840
841 if (num_devices <= 0)
842 return ERROR_FAIL;
843
844 for (i = 0; i < num_devices; i++) {
845 libusb_device *device = usb_devices[i];
846
847 retval = libusb_get_device_descriptor(device, &usb_desc);
848 if (retval != 0)
849 continue;
850
851 if (usb_desc.idVendor != versaloon_interface.usb_setting.vid ||
852 usb_desc.idProduct != versaloon_interface.usb_setting.pid)
853 continue;
854
855 retval = libusb_open(device, &usb_device_handle);
856 if (retval != 0)
857 continue;
858
859 retval = vsllink_check_usb_strings(usb_device_handle, &usb_desc);
860 if (ERROR_OK == retval)
861 break;
862
863 libusb_close(usb_device_handle);
864 }
865
866 libusb_free_device_list(usb_devices, 1);
867
868 if (i == num_devices)
869 return ERROR_FAIL;
870
871 retval = libusb_claim_interface(usb_device_handle,
872 versaloon_interface.usb_setting.interface);
873 if (retval != 0) {
874 LOG_ERROR("unable to claim interface");
875 libusb_close(usb_device_handle);
876 return ERROR_FAIL;
877 }
878
879 vsllink->usb_device_handle = usb_device_handle;
880 return ERROR_OK;
881 }
882
883 static void vsllink_usb_close(struct vsllink *vsllink)
884 {
885 libusb_release_interface(vsllink->usb_device_handle,
886 versaloon_interface.usb_setting.interface);
887 libusb_close(vsllink->usb_device_handle);
888 }
889
890 #define BYTES_PER_LINE 16
891
892 static void vsllink_debug_buffer(uint8_t *buffer, int length)
893 {
894 char line[81];
895 char s[4];
896 int i;
897 int j;
898
899 for (i = 0; i < length; i += BYTES_PER_LINE) {
900 snprintf(line, 5, "%04x", i & 0xffff);
901 for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
902 snprintf(s, 4, " %02x", buffer[j]);
903 strcat(line, s);
904 }
905 LOG_DEBUG_IO("%s", line);
906 }
907 }
908
909 static const struct command_registration vsllink_command_handlers[] = {
910 {
911 .name = "vsllink_usb_vid",
912 .handler = &vsllink_handle_usb_vid_command,
913 .mode = COMMAND_CONFIG,
914 .help = "Set USB VID",
915 .usage = "<vid>",
916 },
917 {
918 .name = "vsllink_usb_pid",
919 .handler = &vsllink_handle_usb_pid_command,
920 .mode = COMMAND_CONFIG,
921 .help = "Set USB PID",
922 .usage = "<pid>",
923 },
924 {
925 .name = "vsllink_usb_serial",
926 .handler = &vsllink_handle_usb_serial_command,
927 .mode = COMMAND_CONFIG,
928 .help = "Set or disable check for USB serial",
929 .usage = "[<serial>]",
930 },
931 {
932 .name = "vsllink_usb_bulkin",
933 .handler = &vsllink_handle_usb_bulkin_command,
934 .mode = COMMAND_CONFIG,
935 .help = "Set USB input endpoint",
936 .usage = "<ep_in>",
937 },
938 {
939 .name = "vsllink_usb_bulkout",
940 .handler = &vsllink_handle_usb_bulkout_command,
941 .mode = COMMAND_CONFIG,
942 .help = "Set USB output endpoint",
943 .usage = "<ep_out>",
944 },
945 {
946 .name = "vsllink_usb_interface",
947 .handler = &vsllink_handle_usb_interface_command,
948 .mode = COMMAND_CONFIG,
949 .help = "Set USB output interface",
950 .usage = "<interface>",
951 },
952 COMMAND_REGISTRATION_DONE
953 };
954
955 static const char * const vsllink_transports[] = {"jtag", "swd", NULL};
956
957 static const struct swd_driver vsllink_swd_driver = {
958 .init = vsllink_swd_init,
959 .switch_seq = vsllink_swd_switch_seq,
960 .read_reg = vsllink_swd_read_reg,
961 .write_reg = vsllink_swd_write_reg,
962 .run = vsllink_swd_run_queue,
963 };
964
965 struct jtag_interface vsllink_interface = {
966 .name = "vsllink",
967 .supported = DEBUG_CAP_TMS_SEQ,
968 .commands = vsllink_command_handlers,
969 .transports = vsllink_transports,
970 .swd = &vsllink_swd_driver,
971
972 .init = vsllink_init,
973 .quit = vsllink_quit,
974 .khz = vsllink_khz,
975 .speed = vsllink_speed,
976 .speed_div = vsllink_speed_div,
977 .execute_queue = vsllink_execute_queue,
978 };

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)