14e59ec74666fd9ff3bcb1a8c90aef1bf4558ca5
[fw/openocd] / src / jtag / stlink / stlink_transport.c
1 /***************************************************************************
2  *   Copyright (C) 2011 by Mathias Kuester                                 *
3  *   Mathias Kuester <kesmtp@freenet.de>                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 /* project specific includes */
26 #include <jtag/interface.h>
27 #include <jtag/tcl.h>
28 #include <transport/transport.h>
29 #include <helper/time_support.h>
30 #include <target/target.h>
31 #include <jtag/stlink/stlink_tcl.h>
32 #include <jtag/stlink/stlink_interface.h>
33
34 COMMAND_HANDLER(stlink_transport_jtag_command)
35 {
36         LOG_DEBUG("stlink_transport_jtag_command");
37
38         return ERROR_OK;
39 }
40
41 static const struct command_registration
42 stlink_transport_stlink_subcommand_handlers[] = {
43         {
44          .name = "newtap",
45          .mode = COMMAND_CONFIG,
46          .jim_handler = jim_stlink_newtap,
47          .help = "Create a new TAP instance named basename.tap_type, "
48          "and appends it to the scan chain.",
49          .usage = "basename tap_type '-irlen' count "
50          "['-expected_id' number] ",
51          },
52
53         COMMAND_REGISTRATION_DONE
54 };
55
56 static const struct command_registration
57 stlink_transport_jtag_subcommand_handlers[] = {
58         {
59          .name = "init",
60          .mode = COMMAND_ANY,
61          .handler = stlink_transport_jtag_command,
62          .usage = ""
63          },
64         {
65          .name = "arp_init",
66          .mode = COMMAND_ANY,
67          .handler = stlink_transport_jtag_command,
68          .usage = ""
69          },
70         {
71          .name = "arp_init-reset",
72          .mode = COMMAND_ANY,
73          .handler = stlink_transport_jtag_command,
74          .usage = ""
75          },
76         {
77          .name = "tapisenabled",
78          .mode = COMMAND_EXEC,
79          .jim_handler = jim_jtag_tap_enabler,
80          },
81         {
82          .name = "tapenable",
83          .mode = COMMAND_EXEC,
84          .jim_handler = jim_jtag_tap_enabler,
85          },
86         {
87          .name = "tapdisable",
88          .mode = COMMAND_EXEC,
89          .handler = stlink_transport_jtag_command,
90          .usage = "",
91          },
92         {
93          .name = "configure",
94          .mode = COMMAND_EXEC,
95          .handler = stlink_transport_jtag_command,
96          .usage = "",
97          },
98         {
99          .name = "cget",
100          .mode = COMMAND_EXEC,
101          .jim_handler = jim_jtag_configure,
102          },
103         {
104          .name = "names",
105          .mode = COMMAND_ANY,
106          .handler = stlink_transport_jtag_command,
107          .usage = "",
108          },
109
110         COMMAND_REGISTRATION_DONE
111 };
112
113 static const struct command_registration stlink_transport_command_handlers[] = {
114
115         {
116          .name = "stlink",
117          .mode = COMMAND_ANY,
118          .help = "perform stlink actions",
119          .usage = "",
120          .chain = stlink_transport_stlink_subcommand_handlers,
121          },
122         {
123          .name = "jtag",
124          .mode = COMMAND_ANY,
125          .usage = "",
126          .chain = stlink_transport_jtag_subcommand_handlers,
127          },
128         COMMAND_REGISTRATION_DONE
129 };
130
131 static int stlink_transport_register_commands(struct command_context *cmd_ctx)
132 {
133         return register_commands(cmd_ctx, NULL,
134                                  stlink_transport_command_handlers);
135 }
136
137 static int stlink_transport_init(struct command_context *cmd_ctx)
138 {
139         LOG_DEBUG("stlink_transport_init");
140         struct target *t = get_current_target(cmd_ctx);
141
142         if (!t) {
143                 LOG_ERROR("stlink_transport_init: no current target");
144                 return ERROR_FAIL;
145         }
146
147         int retval = stlink_interface_open();
148         if (retval != ERROR_OK)
149                 return retval;
150
151         return stlink_interface_init_target(t);
152 }
153
154 static int stlink_transport_select(struct command_context *ctx)
155 {
156         LOG_DEBUG("stlink_transport_select");
157
158         int retval;
159
160         /* NOTE:  interface init must already have been done.
161          * That works with only C code ... no Tcl glue required.
162          */
163
164         retval = stlink_transport_register_commands(ctx);
165
166         if (retval != ERROR_OK)
167                 return retval;
168
169         return ERROR_OK;
170 }
171
172 static struct transport stlink_transport = {
173         .name = "stlink",
174         .select = stlink_transport_select,
175         .init = stlink_transport_init,
176 };
177
178 const char *stlink_transports[] = { "stlink", NULL };
179
180 static void stlink_constructor(void) __attribute__ ((constructor));
181 static void stlink_constructor(void)
182 {
183         transport_register(&stlink_transport);
184 }
185
186 bool transport_is_stlink(void)
187 {
188         return get_current_transport() == &stlink_transport;
189 }