]> git.sur5r.net Git - openocd/blob - src/jtag/stlink/stlink_transport.c
stlink: print version info
[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_transport.h>
33 #include <jtag/stlink/stlink_interface.h>
34
35 COMMAND_HANDLER(stlink_transport_jtag_command)
36 {
37         LOG_DEBUG("stlink_transport_jtag_command");
38
39         return ERROR_OK;
40 }
41
42 COMMAND_HANDLER(stlink_transport_reset_command)
43 {
44         return stlink_interface_init_reset();
45 }
46
47 static const struct command_registration
48 stlink_transport_stlink_subcommand_handlers[] = {
49         {
50          .name = "newtap",
51          .mode = COMMAND_CONFIG,
52          .jim_handler = jim_stlink_newtap,
53          .help = "Create a new TAP instance named basename.tap_type, "
54          "and appends it to the scan chain.",
55          .usage = "basename tap_type '-irlen' count "
56          "['-expected_id' number] ",
57          },
58
59         COMMAND_REGISTRATION_DONE
60 };
61
62 static const struct command_registration
63 stlink_transport_jtag_subcommand_handlers[] = {
64         {
65          .name = "init",
66          .mode = COMMAND_ANY,
67          .handler = stlink_transport_jtag_command,
68          .usage = ""
69          },
70         {
71          .name = "arp_init",
72          .mode = COMMAND_ANY,
73          .handler = stlink_transport_jtag_command,
74          .usage = ""
75          },
76         {
77          .name = "arp_init-reset",
78          .mode = COMMAND_ANY,
79          .handler = stlink_transport_reset_command,
80          .usage = ""
81          },
82         {
83          .name = "tapisenabled",
84          .mode = COMMAND_EXEC,
85          .jim_handler = jim_jtag_tap_enabler,
86          },
87         {
88          .name = "tapenable",
89          .mode = COMMAND_EXEC,
90          .jim_handler = jim_jtag_tap_enabler,
91          },
92         {
93          .name = "tapdisable",
94          .mode = COMMAND_EXEC,
95          .handler = stlink_transport_jtag_command,
96          .usage = "",
97          },
98         {
99          .name = "configure",
100          .mode = COMMAND_EXEC,
101          .handler = stlink_transport_jtag_command,
102          .usage = "",
103          },
104         {
105          .name = "cget",
106          .mode = COMMAND_EXEC,
107          .jim_handler = jim_jtag_configure,
108          },
109         {
110          .name = "names",
111          .mode = COMMAND_ANY,
112          .handler = stlink_transport_jtag_command,
113          .usage = "",
114          },
115
116         COMMAND_REGISTRATION_DONE
117 };
118
119 static const struct command_registration stlink_transport_command_handlers[] = {
120
121         {
122          .name = "stlink",
123          .mode = COMMAND_ANY,
124          .help = "perform stlink actions",
125          .usage = "",
126          .chain = stlink_transport_stlink_subcommand_handlers,
127          },
128         {
129          .name = "jtag",
130          .mode = COMMAND_ANY,
131          .usage = "",
132          .chain = stlink_transport_jtag_subcommand_handlers,
133          },
134         COMMAND_REGISTRATION_DONE
135 };
136
137 static int stlink_transport_register_commands(struct command_context *cmd_ctx)
138 {
139         return register_commands(cmd_ctx, NULL,
140                                  stlink_transport_command_handlers);
141 }
142
143 static int stlink_transport_init(struct command_context *cmd_ctx)
144 {
145         LOG_DEBUG("stlink_transport_init");
146         struct target *t = get_current_target(cmd_ctx);
147         struct transport *transport;
148         enum stlink_transports tr;
149
150         if (!t) {
151                 LOG_ERROR("no current target");
152                 return ERROR_FAIL;
153         }
154
155         transport = get_current_transport();
156
157         if (!transport) {
158                 LOG_ERROR("no transport selected");
159                 return ERROR_FAIL;
160         }
161
162         LOG_DEBUG("current transport %s", transport->name);
163
164         /* get selected transport as enum */
165         tr = STLINK_TRANSPORT_UNKNOWN;
166
167         if (strcmp(transport->name, "stlink_swd") == 0)
168                 tr = STLINK_TRANSPORT_SWD;
169         else if (strcmp(transport->name, "stlink_jtag") == 0)
170                 tr = STLINK_TRANSPORT_JTAG;
171         else if (strcmp(transport->name, "stlink_swim") == 0)
172                 tr = STLINK_TRANSPORT_SWIM;
173
174         int retval = stlink_interface_open(tr);
175
176         if (retval != ERROR_OK)
177                 return retval;
178
179         return stlink_interface_init_target(t);
180 }
181
182 static int stlink_transport_select(struct command_context *ctx)
183 {
184         LOG_DEBUG("stlink_transport_select");
185
186         int retval;
187
188         /* NOTE:  interface init must already have been done.
189          * That works with only C code ... no Tcl glue required.
190          */
191
192         retval = stlink_transport_register_commands(ctx);
193
194         if (retval != ERROR_OK)
195                 return retval;
196
197         return ERROR_OK;
198 }
199
200 static struct transport stlink_swd_transport = {
201         .name = "stlink_swd",
202         .select = stlink_transport_select,
203         .init = stlink_transport_init,
204 };
205
206 static struct transport stlink_jtag_transport = {
207         .name = "stlink_jtag",
208         .select = stlink_transport_select,
209         .init = stlink_transport_init,
210 };
211
212 static struct transport stlink_swim_transport = {
213         .name = "stlink_swim",
214         .select = stlink_transport_select,
215         .init = stlink_transport_init,
216 };
217
218 const char *stlink_transports[] = { "stlink_swd", "stlink_jtag", "stlink_swim", NULL };
219
220 static void stlink_constructor(void) __attribute__ ((constructor));
221 static void stlink_constructor(void)
222 {
223         transport_register(&stlink_swd_transport);
224         transport_register(&stlink_jtag_transport);
225         transport_register(&stlink_swim_transport);
226 }
227
228 bool transport_is_stlink(void)
229 {
230         return get_current_transport() == &stlink_swd_transport;
231 }