1 /***************************************************************************
2 * Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com> *
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. *
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. *
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 ***************************************************************************/
20 /* Versaloon is a programming tool for multiple MCUs.
21 * It's distributed under GPLv3.
22 * You can find it at http://www.Versaloon.com/.
29 #include <jtag/interface.h>
30 #include <jtag/commands.h>
31 #include "usb_common.h"
33 #include "versaloon/versaloon_include.h"
34 #include "versaloon/versaloon.h"
36 static int vsllink_tms_offset
;
38 struct pending_scan_result
{
41 int length
; /* Number of bits to read */
42 struct scan_command
*command
; /* Corresponding scan command */
45 bool last
; /* indicate the last scan pending */
48 #define MAX_PENDING_SCAN_RESULTS 256
50 static int pending_scan_results_length
;
51 static struct pending_scan_result
52 pending_scan_results_buffer
[MAX_PENDING_SCAN_RESULTS
];
54 /* Queue command functions */
55 static void vsllink_end_state(tap_state_t state
);
56 static void vsllink_state_move(void);
57 static void vsllink_path_move(int num_states
, tap_state_t
*path
);
58 static void vsllink_tms(int num_bits
, const uint8_t *bits
);
59 static void vsllink_runtest(int num_cycles
);
60 static void vsllink_stableclocks(int num_cycles
, int tms
);
61 static void vsllink_scan(bool ir_scan
, enum scan_type type
,
62 uint8_t *buffer
, int scan_size
, struct scan_command
*command
);
63 static void vsllink_reset(int trst
, int srst
);
65 /* VSLLink tap buffer functions */
66 static void vsllink_tap_append_step(int tms
, int tdi
);
67 static void vsllink_tap_init(void);
68 static int vsllink_tap_execute(void);
69 static void vsllink_tap_ensure_pending(int scans
);
70 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
71 struct scan_command
*command
);
73 /* VSLLink lowlevel functions */
75 struct usb_dev_handle
*usb_handle
;
78 static struct vsllink
*vsllink_usb_open(void);
79 static void vsllink_usb_close(struct vsllink
*vsllink
);
81 #if defined _DEBUG_JTAG_IO_
82 static void vsllink_debug_buffer(uint8_t *buffer
, int length
);
85 static int tap_length
;
86 static int tap_buffer_size
;
87 static uint8_t *tms_buffer
;
88 static uint8_t *tdi_buffer
;
89 static uint8_t *tdo_buffer
;
91 struct vsllink
*vsllink_handle
;
93 static int vsllink_execute_queue(void)
95 struct jtag_command
*cmd
= jtag_command_queue
;
100 DEBUG_JTAG_IO("-------------------------------------"
102 "-------------------------------------");
104 while (cmd
!= NULL
) {
107 DEBUG_JTAG_IO("runtest %i cycles, end in %s",
108 cmd
->cmd
.runtest
->num_cycles
,
109 tap_state_name(cmd
->cmd
.runtest
->end_state
));
111 vsllink_end_state(cmd
->cmd
.runtest
->end_state
);
112 vsllink_runtest(cmd
->cmd
.runtest
->num_cycles
);
116 DEBUG_JTAG_IO("statemove end in %s",
117 tap_state_name(cmd
->cmd
.statemove
->end_state
));
119 vsllink_end_state(cmd
->cmd
.statemove
->end_state
);
120 vsllink_state_move();
124 DEBUG_JTAG_IO("pathmove: %i states, end in %s",
125 cmd
->cmd
.pathmove
->num_states
,
126 tap_state_name(cmd
->cmd
.pathmove
->path
[cmd
->cmd
.pathmove
->num_states
- 1]));
128 vsllink_path_move(cmd
->cmd
.pathmove
->num_states
, cmd
->cmd
.pathmove
->path
);
132 DEBUG_JTAG_IO("JTAG Scan...");
134 vsllink_end_state(cmd
->cmd
.scan
->end_state
);
136 scan_size
= jtag_build_buffer(
137 cmd
->cmd
.scan
, &buffer
);
139 if (cmd
->cmd
.scan
->ir_scan
)
141 "JTAG Scan write IR(%d bits), "
144 tap_state_name(cmd
->cmd
.scan
->end_state
));
148 "JTAG Scan write DR(%d bits), "
151 tap_state_name(cmd
->cmd
.scan
->end_state
));
153 #ifdef _DEBUG_JTAG_IO_
154 vsllink_debug_buffer(buffer
,
155 DIV_ROUND_UP(scan_size
, 8));
158 type
= jtag_scan_type(cmd
->cmd
.scan
);
160 vsllink_scan(cmd
->cmd
.scan
->ir_scan
,
161 type
, buffer
, scan_size
,
166 DEBUG_JTAG_IO("reset trst: %i srst %i",
167 cmd
->cmd
.reset
->trst
,
168 cmd
->cmd
.reset
->srst
);
170 vsllink_tap_execute();
172 if (cmd
->cmd
.reset
->trst
== 1)
173 tap_set_state(TAP_RESET
);
175 vsllink_reset(cmd
->cmd
.reset
->trst
,
176 cmd
->cmd
.reset
->srst
);
180 DEBUG_JTAG_IO("sleep %i", cmd
->cmd
.sleep
->us
);
181 vsllink_tap_execute();
182 jtag_sleep(cmd
->cmd
.sleep
->us
);
185 case JTAG_STABLECLOCKS
:
186 DEBUG_JTAG_IO("add %d clocks",
187 cmd
->cmd
.stableclocks
->num_cycles
);
189 switch (tap_get_state()) {
191 /* tms must be '1' to stay
201 /* else, tms should be '0' */
204 /* above stable states are OK */
206 LOG_ERROR("jtag_add_clocks() "
207 "in non-stable state \"%s\"",
208 tap_state_name(tap_get_state())
212 vsllink_stableclocks(cmd
->cmd
.stableclocks
->num_cycles
, scan_size
);
216 DEBUG_JTAG_IO("add %d jtag tms",
217 cmd
->cmd
.tms
->num_bits
);
219 vsllink_tms(cmd
->cmd
.tms
->num_bits
, cmd
->cmd
.tms
->bits
);
223 LOG_ERROR("BUG: unknown JTAG command type "
224 "encountered: %d", cmd
->type
);
230 return vsllink_tap_execute();
233 static int vsllink_speed(int speed
)
235 versaloon_interface
.adaptors
.jtag_raw
.config(0, (uint16_t)speed
);
236 return versaloon_interface
.adaptors
.peripheral_commit();
239 static int vsllink_khz(int khz
, int *jtag_speed
)
246 static int vsllink_speed_div(int jtag_speed
, int *khz
)
253 static void vsllink_free_buffer(void)
255 if (tdi_buffer
!= NULL
) {
259 if (tdo_buffer
!= NULL
) {
263 if (tms_buffer
!= NULL
) {
269 static int vsllink_quit(void)
271 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
272 0, 0, GPIO_SRST
| GPIO_TRST
);
273 versaloon_interface
.adaptors
.gpio
.fini(0);
274 versaloon_interface
.adaptors
.jtag_raw
.fini(0);
275 versaloon_interface
.adaptors
.peripheral_commit();
276 versaloon_interface
.fini();
278 vsllink_free_buffer();
279 vsllink_usb_close(vsllink_handle
);
284 static int vsllink_init(void)
286 vsllink_handle
= vsllink_usb_open();
287 if (vsllink_handle
== 0) {
288 LOG_ERROR("Can't find USB JTAG Interface!" \
289 "Please check connection and permissions.");
290 return ERROR_JTAG_INIT_FAILED
;
292 LOG_DEBUG("vsllink found on %04X:%04X",
293 versaloon_interface
.usb_setting
.vid
,
294 versaloon_interface
.usb_setting
.pid
);
295 versaloon_usb_device_handle
= vsllink_handle
->usb_handle
;
297 if (ERROR_OK
!= versaloon_interface
.init())
299 if (versaloon_interface
.usb_setting
.buf_size
< 32) {
300 versaloon_interface
.fini();
304 /* malloc buffer size for tap */
305 tap_buffer_size
= versaloon_interface
.usb_setting
.buf_size
- 32;
306 vsllink_free_buffer();
307 tdi_buffer
= (uint8_t *)malloc(tap_buffer_size
);
308 tdo_buffer
= (uint8_t *)malloc(tap_buffer_size
);
309 tms_buffer
= (uint8_t *)malloc(tap_buffer_size
);
310 if ((NULL
== tdi_buffer
) || (NULL
== tdo_buffer
) || (NULL
== tms_buffer
)) {
315 versaloon_interface
.adaptors
.jtag_raw
.init(0);
316 versaloon_interface
.adaptors
.jtag_raw
.config(0, jtag_get_speed_khz());
317 versaloon_interface
.adaptors
.gpio
.init(0);
318 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
| GPIO_TRST
,
319 GPIO_TRST
, GPIO_SRST
, GPIO_SRST
);
320 if (ERROR_OK
!= versaloon_interface
.adaptors
.peripheral_commit())
328 /**************************************************************************
329 * Queue command implementations */
331 static void vsllink_end_state(tap_state_t state
)
333 if (tap_is_state_stable(state
))
334 tap_set_end_state(state
);
336 LOG_ERROR("BUG: %i is not a valid end state", state
);
341 /* Goes to the end state. */
342 static void vsllink_state_move(void)
345 uint8_t tms_scan
= tap_get_tms_path(tap_get_state(),
346 tap_get_end_state());
347 uint8_t tms_scan_bits
= tap_get_tms_path_len(tap_get_state(),
348 tap_get_end_state());
350 for (i
= 0; i
< tms_scan_bits
; i
++)
351 vsllink_tap_append_step((tms_scan
>> i
) & 1, 0);
353 tap_set_state(tap_get_end_state());
356 static void vsllink_path_move(int num_states
, tap_state_t
*path
)
358 for (int i
= 0; i
< num_states
; i
++) {
359 if (path
[i
] == tap_state_transition(tap_get_state(), false))
360 vsllink_tap_append_step(0, 0);
361 else if (path
[i
] == tap_state_transition(tap_get_state(), true))
362 vsllink_tap_append_step(1, 0);
364 LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
365 tap_state_name(tap_get_state()),
366 tap_state_name(path
[i
]));
370 tap_set_state(path
[i
]);
373 tap_set_end_state(tap_get_state());
376 static void vsllink_tms(int num_bits
, const uint8_t *bits
)
378 for (int i
= 0; i
< num_bits
; i
++)
379 vsllink_tap_append_step((bits
[i
/ 8] >> (i
% 8)) & 1, 0);
382 static void vsllink_stableclocks(int num_cycles
, int tms
)
384 while (num_cycles
> 0) {
385 vsllink_tap_append_step(tms
, 0);
390 static void vsllink_runtest(int num_cycles
)
392 tap_state_t saved_end_state
= tap_get_end_state();
394 if (tap_get_state() != TAP_IDLE
) {
395 /* enter IDLE state */
396 vsllink_end_state(TAP_IDLE
);
397 vsllink_state_move();
400 vsllink_stableclocks(num_cycles
, 0);
404 vsllink_end_state(saved_end_state
);
405 if (tap_get_end_state() != tap_get_end_state())
406 vsllink_state_move();
409 static void vsllink_scan(bool ir_scan
, enum scan_type type
, uint8_t *buffer
,
410 int scan_size
, struct scan_command
*command
)
412 tap_state_t saved_end_state
;
414 saved_end_state
= tap_get_end_state();
416 /* Move to appropriate scan state */
417 vsllink_end_state(ir_scan
? TAP_IRSHIFT
: TAP_DRSHIFT
);
419 if (tap_get_state() != tap_get_end_state())
420 vsllink_state_move();
421 vsllink_end_state(saved_end_state
);
424 vsllink_tap_append_scan(scan_size
, buffer
, command
);
426 /* Goto Pause and record position to insert tms:0 */
427 vsllink_tap_append_step(0, 0);
428 vsllink_tms_offset
= tap_length
;
430 tap_set_state(ir_scan
? TAP_IRPAUSE
: TAP_DRPAUSE
);
432 if (tap_get_state() != tap_get_end_state())
433 vsllink_state_move();
436 static void vsllink_reset(int trst
, int srst
)
438 LOG_DEBUG("trst: %i, srst: %i", trst
, srst
);
441 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, 0, GPIO_SRST
, GPIO_SRST
);
443 versaloon_interface
.adaptors
.gpio
.config(0, GPIO_SRST
, GPIO_SRST
, 0, 0);
446 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, GPIO_TRST
);
448 versaloon_interface
.adaptors
.gpio
.out(0, GPIO_TRST
, 0);
449 versaloon_interface
.adaptors
.peripheral_commit();
452 COMMAND_HANDLER(vsllink_handle_usb_vid_command
)
455 return ERROR_COMMAND_SYNTAX_ERROR
;
457 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
458 versaloon_interface
.usb_setting
.vid
);
462 COMMAND_HANDLER(vsllink_handle_usb_pid_command
)
465 return ERROR_COMMAND_SYNTAX_ERROR
;
466 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0],
467 versaloon_interface
.usb_setting
.pid
);
471 COMMAND_HANDLER(vsllink_handle_usb_bulkin_command
)
474 return ERROR_COMMAND_SYNTAX_ERROR
;
476 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
477 versaloon_interface
.usb_setting
.ep_in
);
479 versaloon_interface
.usb_setting
.ep_in
|= 0x80;
484 COMMAND_HANDLER(vsllink_handle_usb_bulkout_command
)
487 return ERROR_COMMAND_SYNTAX_ERROR
;
489 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
490 versaloon_interface
.usb_setting
.ep_out
);
492 versaloon_interface
.usb_setting
.ep_out
&= ~0x80;
497 COMMAND_HANDLER(vsllink_handle_usb_interface_command
)
500 return ERROR_COMMAND_SYNTAX_ERROR
;
502 COMMAND_PARSE_NUMBER(u8
, CMD_ARGV
[0],
503 versaloon_interface
.usb_setting
.interface
);
507 /**************************************************************************
508 * VSLLink tap functions */
510 static void vsllink_tap_init(void)
513 pending_scan_results_length
= 0;
514 vsllink_tms_offset
= 0;
517 static void vsllink_tap_ensure_pending(int scans
)
519 int available_scans
=
520 MAX_PENDING_SCAN_RESULTS
- pending_scan_results_length
;
522 if (scans
> available_scans
)
523 vsllink_tap_execute();
526 static void vsllink_tap_append_step(int tms
, int tdi
)
528 int index_var
= tap_length
/ 8;
530 int bit_index
= tap_length
% 8;
531 uint8_t bit
= 1 << bit_index
;
534 tms_buffer
[index_var
] |= bit
;
536 tms_buffer
[index_var
] &= ~bit
;
539 tdi_buffer
[index_var
] |= bit
;
541 tdi_buffer
[index_var
] &= ~bit
;
545 if (tap_buffer_size
* 8 <= tap_length
)
546 vsllink_tap_execute();
549 static void vsllink_tap_append_scan(int length
, uint8_t *buffer
,
550 struct scan_command
*command
)
552 struct pending_scan_result
*pending_scan_result
;
553 int len_tmp
, len_all
, i
;
556 while (len_all
< length
) {
557 vsllink_tap_ensure_pending(1);
558 pending_scan_result
=
559 &pending_scan_results_buffer
[
560 pending_scan_results_length
];
562 if ((length
- len_all
) > (tap_buffer_size
* 8 - tap_length
)) {
563 /* Use all memory available
564 vsllink_tap_append_step will commit automatically */
565 len_tmp
= tap_buffer_size
* 8 - tap_length
;
566 pending_scan_result
->last
= false;
568 len_tmp
= length
- len_all
;
569 pending_scan_result
->last
= true;
571 pending_scan_result
->src_offset
= tap_length
;
572 pending_scan_result
->dest_offset
= len_all
;
573 pending_scan_result
->length
= len_tmp
;
574 pending_scan_result
->command
= command
;
575 pending_scan_result
->buffer
= buffer
;
576 pending_scan_results_length
++;
578 for (i
= 0; i
< len_tmp
; i
++) {
579 vsllink_tap_append_step(((len_all
+ i
) < length
-1
581 (buffer
[(len_all
+ i
)/8]
582 >> ((len_all
+ i
)%8)) & 1);
589 static int vsllink_jtag_execute(void)
597 versaloon_interface
.adaptors
.jtag_raw
.execute(0, tdi_buffer
, tms_buffer
,
598 tdo_buffer
, tap_length
);
600 result
= versaloon_interface
.adaptors
.peripheral_commit();
602 if (result
== ERROR_OK
) {
603 for (i
= 0; i
< pending_scan_results_length
; i
++) {
604 struct pending_scan_result
*pending_scan_result
=
605 &pending_scan_results_buffer
[i
];
606 uint8_t *buffer
= pending_scan_result
->buffer
;
607 int length
= pending_scan_result
->length
;
608 int src_first
= pending_scan_result
->src_offset
;
609 int dest_first
= pending_scan_result
->dest_offset
;
610 bool last
= pending_scan_result
->last
;
612 struct scan_command
*command
;
614 command
= pending_scan_result
->command
;
615 buf_set_buf(tdo_buffer
, src_first
, buffer
, dest_first
, length
);
617 #ifdef _DEBUG_JTAG_IO_
619 "JTAG scan read(%d bits, from src %d bits to dest %d bits):",
620 length
, src_first
, dest_first
);
621 vsllink_debug_buffer(buffer
+ dest_first
/ 8,
622 DIV_ROUND_UP(length
, 7));
626 if (jtag_read_buffer(buffer
, command
)
629 return ERROR_JTAG_QUEUE_FAILED
;
632 if (pending_scan_result
->buffer
!= NULL
)
633 free(pending_scan_result
->buffer
);
637 LOG_ERROR("vsllink_jtag_execute failure");
638 return ERROR_JTAG_QUEUE_FAILED
;
646 static int vsllink_tap_execute(void)
648 return vsllink_jtag_execute();
651 /****************************************************************************
652 * VSLLink USB low-level functions */
654 static uint8_t usb_check_string(usb_dev_handle
*usb
, uint8_t stringidx
,
655 char *string
, char *buff
, uint16_t buf_size
)
663 buff
= (char *)malloc(buf_size
);
666 goto free_and_return
;
672 len
= usb_get_string_simple(usb
, stringidx
, (char *)buff
, buf_size
);
673 if ((len
< 0) || (len
!= ((int)strlen((const char *)buff
)))) {
675 goto free_and_return
;
679 if ((string
!= NULL
) && strcmp((const char *)buff
, string
)) {
681 goto free_and_return
;
685 if (alloced
&& (buff
!= NULL
)) {
692 static usb_dev_handle
*find_usb_device(uint16_t VID
, uint16_t PID
,
693 uint8_t interface
, int8_t serialindex
, char *serialstring
,
694 int8_t productindex
, char *productstring
)
696 usb_dev_handle
*dev_handle
= NULL
;
697 struct usb_bus
*busses
;
699 struct usb_device
*dev
;
704 busses
= usb_get_busses();
706 for (bus
= busses
; bus
; bus
= bus
->next
) {
707 for (dev
= bus
->devices
; dev
; dev
= dev
->next
) {
708 if ((dev
->descriptor
.idVendor
== VID
)
709 && (dev
->descriptor
.idProduct
== PID
)) {
710 dev_handle
= usb_open(dev
);
711 if (NULL
== dev_handle
) {
712 LOG_ERROR("failed to open %04X:%04X, %s", VID
, PID
,
717 /* check description string */
718 if (((productstring
!= NULL
) && (productindex
>= 0)
719 && !usb_check_string(dev_handle
, productindex
,
720 productstring
, NULL
, 0))
721 || ((serialstring
!= NULL
) && (serialindex
>= 0)
722 && !usb_check_string(dev_handle
, serialindex
,
723 serialstring
, NULL
, 0))) {
724 usb_close(dev_handle
);
729 if (usb_claim_interface(dev_handle
, interface
) != 0) {
730 LOG_ERROR(ERRMSG_FAILURE_OPERATION_MESSAGE
,
731 "claim interface", usb_strerror());
732 usb_close(dev_handle
);
737 if (dev_handle
!= NULL
)
746 static struct vsllink
*vsllink_usb_open(void)
750 struct usb_dev_handle
*dev
;
752 dev
= find_usb_device(versaloon_interface
.usb_setting
.vid
,
753 versaloon_interface
.usb_setting
.pid
,
754 versaloon_interface
.usb_setting
.interface
,
755 0, NULL
, 2, "Versaloon");
759 struct vsllink
*result
= malloc(sizeof(struct vsllink
));
760 result
->usb_handle
= dev
;
764 static void vsllink_usb_close(struct vsllink
*vsllink
)
768 ret
= usb_release_interface(vsllink
->usb_handle
,
769 versaloon_interface
.usb_setting
.interface
);
771 LOG_ERROR("fail to release interface %d, %d returned",
772 versaloon_interface
.usb_setting
.interface
, ret
);
776 ret
= usb_close(vsllink
->usb_handle
);
778 LOG_ERROR("fail to close usb, %d returned", ret
);
785 #define BYTES_PER_LINE 16
787 #if defined _DEBUG_JTAG_IO_
788 static void vsllink_debug_buffer(uint8_t *buffer
, int length
)
795 for (i
= 0; i
< length
; i
+= BYTES_PER_LINE
) {
796 snprintf(line
, 5, "%04x", i
);
797 for (j
= i
; j
< i
+ BYTES_PER_LINE
&& j
< length
; j
++) {
798 snprintf(s
, 4, " %02x", buffer
[j
]);
801 LOG_DEBUG("%s", line
);
804 #endif /* _DEBUG_JTAG_IO_ */
806 static const struct command_registration vsllink_command_handlers
[] = {
808 .name
= "vsllink_usb_vid",
809 .handler
= &vsllink_handle_usb_vid_command
,
810 .mode
= COMMAND_CONFIG
,
813 .name
= "vsllink_usb_pid",
814 .handler
= &vsllink_handle_usb_pid_command
,
815 .mode
= COMMAND_CONFIG
,
818 .name
= "vsllink_usb_bulkin",
819 .handler
= &vsllink_handle_usb_bulkin_command
,
820 .mode
= COMMAND_CONFIG
,
823 .name
= "vsllink_usb_bulkout",
824 .handler
= &vsllink_handle_usb_bulkout_command
,
825 .mode
= COMMAND_CONFIG
,
828 .name
= "vsllink_usb_interface",
829 .handler
= &vsllink_handle_usb_interface_command
,
830 .mode
= COMMAND_CONFIG
,
832 COMMAND_REGISTRATION_DONE
835 static const char *vsllink_transports
[] = {"jtag", "swd", NULL
};
837 struct jtag_interface vsllink_interface
= {
839 .supported
= DEBUG_CAP_TMS_SEQ
,
840 .commands
= vsllink_command_handlers
,
841 .transports
= vsllink_transports
,
843 .init
= vsllink_init
,
844 .quit
= vsllink_quit
,
846 .speed
= vsllink_speed
,
847 .speed_div
= vsllink_speed_div
,
848 .execute_queue
= vsllink_execute_queue
,