1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
3 * Mathias Kuester <kesmtp@freenet.de> *
5 * Copyright (C) 2012 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
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. *
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. *
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 ***************************************************************************/
26 /* project specific includes */
27 #include <jtag/interface.h>
28 #include <transport/transport.h>
29 #include <helper/time_support.h>
31 #include <jtag/hla/hla_tcl.h>
32 #include <jtag/hla/hla_layout.h>
33 #include <jtag/hla/hla_transport.h>
34 #include <jtag/hla/hla_interface.h>
36 #include <target/target.h>
38 static struct hl_interface_s hl_if
= { {0, 0, { 0 }, { 0 }, 0, HL_TRANSPORT_UNKNOWN
, false, -1}, 0, 0 };
40 int hl_interface_open(enum hl_transports tr
)
42 LOG_DEBUG("hl_interface_open");
44 enum reset_types jtag_reset_config
= jtag_get_reset_config();
46 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
47 if (jtag_reset_config
& RESET_SRST_NO_GATING
)
48 hl_if
.param
.connect_under_reset
= true;
50 LOG_WARNING("\'srst_nogate\' reset_config option is required");
53 /* set transport mode */
54 hl_if
.param
.transport
= tr
;
56 int result
= hl_if
.layout
->open(&hl_if
);
57 if (result
!= ERROR_OK
)
60 return hl_interface_init_reset();
63 int hl_interface_init_target(struct target
*t
)
67 LOG_DEBUG("hl_interface_init_target");
69 /* this is the interface for the current target and we
70 * can setup the private pointer in the tap structure
71 * if the interface match the tap idcode
73 res
= hl_if
.layout
->api
->idcode(hl_if
.handle
, &t
->tap
->idcode
);
78 unsigned ii
, limit
= t
->tap
->expected_ids_cnt
;
81 for (ii
= 0; ii
< limit
; ii
++) {
82 uint32_t expected
= t
->tap
->expected_ids
[ii
];
84 /* treat "-expected-id 0" as a "don't-warn" wildcard */
85 if (!expected
|| !t
->tap
->idcode
||
86 (t
->tap
->idcode
== expected
)) {
93 LOG_WARNING("UNEXPECTED idcode: 0x%08" PRIx32
, t
->tap
->idcode
);
94 for (ii
= 0; ii
< limit
; ii
++)
95 LOG_ERROR("expected %u of %u: 0x%08" PRIx32
, ii
+ 1, limit
,
96 t
->tap
->expected_ids
[ii
]);
101 t
->tap
->priv
= &hl_if
;
102 t
->tap
->hasidcode
= 1;
107 static int hl_interface_init(void)
109 LOG_DEBUG("hl_interface_init");
111 /* here we can initialize the layout */
112 return hl_layout_init(&hl_if
);
115 static int hl_interface_quit(void)
117 LOG_DEBUG("hl_interface_quit");
119 if (hl_if
.layout
->api
->close
)
120 hl_if
.layout
->api
->close(hl_if
.handle
);
122 jtag_command_queue_reset();
124 free((void *)hl_if
.param
.device_desc
);
125 free((void *)hl_if
.param
.serial
);
130 static int hl_interface_execute_queue(void)
132 LOG_DEBUG("hl_interface_execute_queue: ignored");
137 int hl_interface_init_reset(void)
139 /* incase the adapter has not already handled asserting srst
140 * we will attempt it again */
141 if (hl_if
.param
.connect_under_reset
) {
142 jtag_add_reset(0, 1);
143 hl_if
.layout
->api
->assert_srst(hl_if
.handle
, 0);
145 jtag_add_reset(0, 0);
151 static int hl_interface_khz(int khz
, int *jtag_speed
)
153 if (hl_if
.layout
->api
->speed
== NULL
)
156 *jtag_speed
= hl_if
.layout
->api
->speed(hl_if
.handle
, khz
, true);
160 static int hl_interface_speed_div(int speed
, int *khz
)
166 static int hl_interface_speed(int speed
)
168 if (hl_if
.layout
->api
->speed
== NULL
)
171 if (hl_if
.handle
== NULL
) {
172 /* pass speed as initial param as interface not open yet */
173 hl_if
.param
.initial_interface_speed
= speed
;
177 hl_if
.layout
->api
->speed(hl_if
.handle
, speed
, false);
182 int hl_interface_override_target(const char **targetname
)
184 if (hl_if
.layout
->api
->override_target
) {
185 if (hl_if
.layout
->api
->override_target(*targetname
)) {
186 *targetname
= "hla_target";
194 int hl_interface_config_trace(bool enabled
, enum tpiu_pin_protocol pin_protocol
,
195 uint32_t port_size
, unsigned int *trace_freq
,
196 unsigned int traceclkin_freq
, uint16_t *prescaler
)
198 if (hl_if
.layout
->api
->config_trace
)
199 return hl_if
.layout
->api
->config_trace(hl_if
.handle
, enabled
,
200 pin_protocol
, port_size
, trace_freq
, traceclkin_freq
, prescaler
);
202 LOG_ERROR("The selected interface does not support tracing");
209 int hl_interface_poll_trace(uint8_t *buf
, size_t *size
)
211 if (hl_if
.layout
->api
->poll_trace
)
212 return hl_if
.layout
->api
->poll_trace(hl_if
.handle
, buf
, size
);
217 COMMAND_HANDLER(hl_interface_handle_device_desc_command
)
219 LOG_DEBUG("hl_interface_handle_device_desc_command");
222 hl_if
.param
.device_desc
= strdup(CMD_ARGV
[0]);
224 LOG_ERROR("expected exactly one argument to hl_device_desc <description>");
230 COMMAND_HANDLER(hl_interface_handle_serial_command
)
232 LOG_DEBUG("hl_interface_handle_serial_command");
235 hl_if
.param
.serial
= strdup(CMD_ARGV
[0]);
237 LOG_ERROR("expected exactly one argument to hl_serial <serial-number>");
243 COMMAND_HANDLER(hl_interface_handle_layout_command
)
245 LOG_DEBUG("hl_interface_handle_layout_command");
248 LOG_ERROR("Need exactly one argument to stlink_layout");
249 return ERROR_COMMAND_SYNTAX_ERROR
;
253 LOG_ERROR("already specified hl_layout %s",
255 return (strcmp(hl_if
.layout
->name
, CMD_ARGV
[0]) != 0)
256 ? ERROR_FAIL
: ERROR_OK
;
259 for (const struct hl_layout
*l
= hl_layout_get_list(); l
->name
;
261 if (strcmp(l
->name
, CMD_ARGV
[0]) == 0) {
267 LOG_ERROR("No adapter layout '%s' found", CMD_ARGV
[0]);
271 COMMAND_HANDLER(hl_interface_handle_vid_pid_command
)
273 if (CMD_ARGC
> HLA_MAX_USB_IDS
* 2) {
274 LOG_WARNING("ignoring extra IDs in hla_vid_pid "
275 "(maximum is %d pairs)", HLA_MAX_USB_IDS
);
276 CMD_ARGC
= HLA_MAX_USB_IDS
* 2;
278 if (CMD_ARGC
< 2 || (CMD_ARGC
& 1)) {
279 LOG_WARNING("incomplete hla_vid_pid configuration directive");
280 return ERROR_COMMAND_SYNTAX_ERROR
;
284 for (i
= 0; i
< CMD_ARGC
; i
+= 2) {
285 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[i
], hl_if
.param
.vid
[i
/ 2]);
286 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[i
+ 1], hl_if
.param
.pid
[i
/ 2]);
290 * Explicitly terminate, in case there are multiple instances of
293 hl_if
.param
.vid
[i
/ 2] = hl_if
.param
.pid
[i
/ 2] = 0;
298 COMMAND_HANDLER(interface_handle_hla_command
)
301 return ERROR_COMMAND_SYNTAX_ERROR
;
303 if (!hl_if
.layout
->api
->custom_command
) {
304 LOG_ERROR("The selected adapter doesn't support custom commands");
308 hl_if
.layout
->api
->custom_command(hl_if
.handle
, CMD_ARGV
[0]);
313 static const struct command_registration hl_interface_command_handlers
[] = {
315 .name
= "hla_device_desc",
316 .handler
= &hl_interface_handle_device_desc_command
,
317 .mode
= COMMAND_CONFIG
,
318 .help
= "set the a device description of the adapter",
319 .usage
= "description_string",
322 .name
= "hla_serial",
323 .handler
= &hl_interface_handle_serial_command
,
324 .mode
= COMMAND_CONFIG
,
325 .help
= "set the serial number of the adapter",
326 .usage
= "serial_string",
329 .name
= "hla_layout",
330 .handler
= &hl_interface_handle_layout_command
,
331 .mode
= COMMAND_CONFIG
,
332 .help
= "set the layout of the adapter",
333 .usage
= "layout_name",
336 .name
= "hla_vid_pid",
337 .handler
= &hl_interface_handle_vid_pid_command
,
338 .mode
= COMMAND_CONFIG
,
339 .help
= "the vendor and product ID of the adapter",
340 .usage
= "(vid pid)* ",
343 .name
= "hla_command",
344 .handler
= &interface_handle_hla_command
,
345 .mode
= COMMAND_EXEC
,
346 .help
= "execute a custom adapter-specific command",
347 .usage
= "hla_command <command>",
349 COMMAND_REGISTRATION_DONE
352 struct jtag_interface hl_interface
= {
355 .commands
= hl_interface_command_handlers
,
356 .transports
= hl_transports
,
357 .init
= hl_interface_init
,
358 .quit
= hl_interface_quit
,
359 .execute_queue
= hl_interface_execute_queue
,
360 .speed
= &hl_interface_speed
,
361 .khz
= &hl_interface_khz
,
362 .speed_div
= &hl_interface_speed_div
,
363 .config_trace
= &hl_interface_config_trace
,
364 .poll_trace
= &hl_interface_poll_trace
,