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