ae7cbb1ac875e7a5779803c6e127b9c0d48f4002
[fw/openocd] / src / jtag / hla / hla_transport.c
1 /***************************************************************************
2  *   Copyright (C) 2011 by Mathias Kuester                                 *
3  *   Mathias Kuester <kesmtp@freenet.de>                                   *
4  *                                                                         *
5  *   Copyright (C) 2012 by Spencer Oliver                                  *
6  *   spen@spen-soft.co.uk                                                  *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
22  ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 /* project specific includes */
29 #include <jtag/interface.h>
30 #include <jtag/tcl.h>
31 #include <transport/transport.h>
32 #include <helper/time_support.h>
33 #include <target/target.h>
34 #include <jtag/hla/hla_tcl.h>
35 #include <jtag/hla/hla_transport.h>
36 #include <jtag/hla/hla_interface.h>
37
38 COMMAND_HANDLER(hl_transport_jtag_command)
39 {
40         LOG_DEBUG("hl_transport_jtag_command");
41
42         return ERROR_OK;
43 }
44
45 COMMAND_HANDLER(hl_transport_reset_command)
46 {
47         return hl_interface_init_reset();
48 }
49
50 static const struct command_registration
51 hl_transport_stlink_subcommand_handlers[] = {
52         {
53          .name = "newtap",
54          .mode = COMMAND_CONFIG,
55          .jim_handler = jim_hl_newtap,
56          .help = "Create a new TAP instance named basename.tap_type, "
57          "and appends it to the scan chain.",
58          .usage = "basename tap_type '-irlen' count "
59          "['-expected_id' number] ",
60          },
61
62         COMMAND_REGISTRATION_DONE
63 };
64
65 static const struct command_registration
66 hl_transport_jtag_subcommand_handlers[] = {
67         {
68          .name = "init",
69          .mode = COMMAND_ANY,
70          .handler = hl_transport_jtag_command,
71          .usage = ""
72          },
73         {
74          .name = "arp_init",
75          .mode = COMMAND_ANY,
76          .handler = hl_transport_jtag_command,
77          .usage = ""
78          },
79         {
80          .name = "arp_init-reset",
81          .mode = COMMAND_ANY,
82          .handler = hl_transport_reset_command,
83          .usage = ""
84          },
85         {
86          .name = "tapisenabled",
87          .mode = COMMAND_EXEC,
88          .jim_handler = jim_jtag_tap_enabler,
89          },
90         {
91          .name = "tapenable",
92          .mode = COMMAND_EXEC,
93          .jim_handler = jim_jtag_tap_enabler,
94          },
95         {
96          .name = "tapdisable",
97          .mode = COMMAND_EXEC,
98          .handler = hl_transport_jtag_command,
99          .usage = "",
100          },
101         {
102          .name = "configure",
103          .mode = COMMAND_EXEC,
104          .handler = hl_transport_jtag_command,
105          .usage = "",
106          },
107         {
108          .name = "cget",
109          .mode = COMMAND_EXEC,
110          .jim_handler = jim_jtag_configure,
111          },
112         {
113          .name = "names",
114          .mode = COMMAND_ANY,
115          .handler = hl_transport_jtag_command,
116          .usage = "",
117          },
118
119         COMMAND_REGISTRATION_DONE
120 };
121
122 static const struct command_registration stlink_transport_command_handlers[] = {
123
124         {
125          .name = "hla",
126          .mode = COMMAND_ANY,
127          .help = "perform hl adapter actions",
128          .usage = "",
129          .chain = hl_transport_stlink_subcommand_handlers,
130          },
131         {
132          .name = "jtag",
133          .mode = COMMAND_ANY,
134          .usage = "",
135          .chain = hl_transport_jtag_subcommand_handlers,
136          },
137         {
138          .name = "jtag_ntrst_delay",
139          .mode = COMMAND_ANY,
140          .handler = hl_transport_jtag_command,
141          .usage = "",
142          },
143         COMMAND_REGISTRATION_DONE
144 };
145
146 static int hl_transport_register_commands(struct command_context *cmd_ctx)
147 {
148         return register_commands(cmd_ctx, NULL,
149                                  stlink_transport_command_handlers);
150 }
151
152 static int hl_transport_init(struct command_context *cmd_ctx)
153 {
154         LOG_DEBUG("hl_transport_init");
155         struct target *t = get_current_target(cmd_ctx);
156         struct transport *transport;
157         enum hl_transports tr;
158
159         if (!t) {
160                 LOG_ERROR("no current target");
161                 return ERROR_FAIL;
162         }
163
164         transport = get_current_transport();
165
166         if (!transport) {
167                 LOG_ERROR("no transport selected");
168                 return ERROR_FAIL;
169         }
170
171         LOG_DEBUG("current transport %s", transport->name);
172
173         /* get selected transport as enum */
174         tr = HL_TRANSPORT_UNKNOWN;
175
176         if (strcmp(transport->name, "hla_swd") == 0)
177                 tr = HL_TRANSPORT_SWD;
178         else if (strcmp(transport->name, "hla_jtag") == 0)
179                 tr = HL_TRANSPORT_JTAG;
180         else if (strcmp(transport->name, "stlink_swim") == 0)
181                 tr = HL_TRANSPORT_SWIM;
182
183         int retval = hl_interface_open(tr);
184
185         if (retval != ERROR_OK)
186                 return retval;
187
188         return hl_interface_init_target(t);
189 }
190
191 static int hl_transport_select(struct command_context *ctx)
192 {
193         LOG_DEBUG("hl_transport_select");
194
195         int retval;
196
197         /* NOTE:  interface init must already have been done.
198          * That works with only C code ... no Tcl glue required.
199          */
200
201         retval = hl_transport_register_commands(ctx);
202
203         if (retval != ERROR_OK)
204                 return retval;
205
206         return ERROR_OK;
207 }
208
209 static struct transport hl_swd_transport = {
210         .name = "hla_swd",
211         .select = hl_transport_select,
212         .init = hl_transport_init,
213         .override_target = hl_interface_override_target,
214 };
215
216 static struct transport hl_jtag_transport = {
217         .name = "hla_jtag",
218         .select = hl_transport_select,
219         .init = hl_transport_init,
220         .override_target = hl_interface_override_target,
221 };
222
223 static struct transport stlink_swim_transport = {
224         .name = "stlink_swim",
225         .select = hl_transport_select,
226         .init = hl_transport_init,
227 };
228
229 const char *hl_transports[] = { "hla_swd", "hla_jtag", "stlink_swim", NULL };
230
231 static void hl_constructor(void) __attribute__ ((constructor));
232 static void hl_constructor(void)
233 {
234         transport_register(&hl_swd_transport);
235         transport_register(&hl_jtag_transport);
236         transport_register(&stlink_swim_transport);
237 }