fbdddfd651de724487688e3bdb36d986c70b0fc1
[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, see <http://www.gnu.org/licenses/>. *
20  ***************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 /* project specific includes */
27 #include <jtag/interface.h>
28 #include <jtag/tcl.h>
29 #include <transport/transport.h>
30 #include <helper/time_support.h>
31 #include <target/target.h>
32 #include <jtag/hla/hla_tcl.h>
33 #include <jtag/hla/hla_transport.h>
34 #include <jtag/hla/hla_interface.h>
35
36 COMMAND_HANDLER(hl_transport_jtag_command)
37 {
38         LOG_DEBUG("hl_transport_jtag_command");
39
40         return ERROR_OK;
41 }
42
43 COMMAND_HANDLER(hl_transport_reset_command)
44 {
45         return hl_interface_init_reset();
46 }
47
48 static const struct command_registration
49 hl_transport_stlink_subcommand_handlers[] = {
50         {
51          .name = "newtap",
52          .mode = COMMAND_CONFIG,
53          .jim_handler = jim_hl_newtap,
54          .help = "Create a new TAP instance named basename.tap_type, "
55          "and appends it to the scan chain.",
56          .usage = "basename tap_type '-irlen' count "
57          "['-expected_id' number] ",
58          },
59
60         COMMAND_REGISTRATION_DONE
61 };
62
63 static const struct command_registration
64 hl_transport_jtag_subcommand_handlers[] = {
65         {
66          .name = "init",
67          .mode = COMMAND_ANY,
68          .handler = hl_transport_jtag_command,
69          .usage = ""
70          },
71         {
72          .name = "arp_init",
73          .mode = COMMAND_ANY,
74          .handler = hl_transport_jtag_command,
75          .usage = ""
76          },
77         {
78          .name = "arp_init-reset",
79          .mode = COMMAND_ANY,
80          .handler = hl_transport_reset_command,
81          .usage = ""
82          },
83         {
84          .name = "tapisenabled",
85          .mode = COMMAND_EXEC,
86          .jim_handler = jim_jtag_tap_enabler,
87          },
88         {
89          .name = "tapenable",
90          .mode = COMMAND_EXEC,
91          .jim_handler = jim_jtag_tap_enabler,
92          },
93         {
94          .name = "tapdisable",
95          .mode = COMMAND_EXEC,
96          .handler = hl_transport_jtag_command,
97          .usage = "",
98          },
99         {
100          .name = "configure",
101          .mode = COMMAND_EXEC,
102          .handler = hl_transport_jtag_command,
103          .usage = "",
104          },
105         {
106          .name = "cget",
107          .mode = COMMAND_EXEC,
108          .jim_handler = jim_jtag_configure,
109          },
110         {
111          .name = "names",
112          .mode = COMMAND_ANY,
113          .handler = hl_transport_jtag_command,
114          .usage = "",
115          },
116
117         COMMAND_REGISTRATION_DONE
118 };
119
120 static const struct command_registration stlink_transport_command_handlers[] = {
121
122         {
123          .name = "hla",
124          .mode = COMMAND_ANY,
125          .help = "perform hl adapter actions",
126          .usage = "",
127          .chain = hl_transport_stlink_subcommand_handlers,
128          },
129         {
130          .name = "jtag",
131          .mode = COMMAND_ANY,
132          .usage = "",
133          .chain = hl_transport_jtag_subcommand_handlers,
134          },
135         {
136          .name = "jtag_ntrst_delay",
137          .mode = COMMAND_ANY,
138          .handler = hl_transport_jtag_command,
139          .usage = "",
140          },
141         COMMAND_REGISTRATION_DONE
142 };
143
144 static int hl_transport_register_commands(struct command_context *cmd_ctx)
145 {
146         return register_commands(cmd_ctx, NULL,
147                                  stlink_transport_command_handlers);
148 }
149
150 static int hl_transport_init(struct command_context *cmd_ctx)
151 {
152         LOG_DEBUG("hl_transport_init");
153         struct target *t = get_current_target(cmd_ctx);
154         struct transport *transport;
155         enum hl_transports tr;
156
157         if (!t) {
158                 LOG_ERROR("no current target");
159                 return ERROR_FAIL;
160         }
161
162         transport = get_current_transport();
163
164         if (!transport) {
165                 LOG_ERROR("no transport selected");
166                 return ERROR_FAIL;
167         }
168
169         LOG_DEBUG("current transport %s", transport->name);
170
171         /* get selected transport as enum */
172         tr = HL_TRANSPORT_UNKNOWN;
173
174         if (strcmp(transport->name, "hla_swd") == 0)
175                 tr = HL_TRANSPORT_SWD;
176         else if (strcmp(transport->name, "hla_jtag") == 0)
177                 tr = HL_TRANSPORT_JTAG;
178
179         int retval = hl_interface_open(tr);
180
181         if (retval != ERROR_OK)
182                 return retval;
183
184         return hl_interface_init_target(t);
185 }
186
187 static int hl_transport_select(struct command_context *ctx)
188 {
189         LOG_DEBUG("hl_transport_select");
190
191         int retval;
192
193         /* NOTE:  interface init must already have been done.
194          * That works with only C code ... no Tcl glue required.
195          */
196
197         retval = hl_transport_register_commands(ctx);
198
199         if (retval != ERROR_OK)
200                 return retval;
201
202         return ERROR_OK;
203 }
204
205 static struct transport hl_swd_transport = {
206         .name = "hla_swd",
207         .select = hl_transport_select,
208         .init = hl_transport_init,
209         .override_target = hl_interface_override_target,
210 };
211
212 static struct transport hl_jtag_transport = {
213         .name = "hla_jtag",
214         .select = hl_transport_select,
215         .init = hl_transport_init,
216         .override_target = hl_interface_override_target,
217 };
218
219 const char *hl_transports[] = { "hla_swd", "hla_jtag", NULL };
220
221 static void hl_constructor(void) __attribute__ ((constructor));
222 static void hl_constructor(void)
223 {
224         transport_register(&hl_swd_transport);
225         transport_register(&hl_jtag_transport);
226 }
227
228 bool transport_is_hla(void)
229 {
230         struct transport *t;
231         t = get_current_transport();
232         return t == &hl_swd_transport || t == &hl_jtag_transport;
233 }