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 }, HL_TRANSPORT_UNKNOWN
, false, -1, false, 7184}, 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_reset(int req_trst
, int req_srst
)
132 return hl_if
.layout
->api
->assert_srst(hl_if
.handle
, req_srst
? 0 : 1);
135 int hl_interface_init_reset(void)
137 /* in case the adapter has not already handled asserting srst
138 * we will attempt it again */
139 if (hl_if
.param
.connect_under_reset
) {
140 adapter_assert_reset();
142 adapter_deassert_reset();
148 static int hl_interface_khz(int khz
, int *jtag_speed
)
150 if (hl_if
.layout
->api
->speed
== NULL
)
153 *jtag_speed
= hl_if
.layout
->api
->speed(hl_if
.handle
, khz
, true);
157 static int hl_interface_speed_div(int speed
, int *khz
)
163 static int hl_interface_speed(int speed
)
165 if (hl_if
.layout
->api
->speed
== NULL
)
168 if (hl_if
.handle
== NULL
) {
169 /* pass speed as initial param as interface not open yet */
170 hl_if
.param
.initial_interface_speed
= speed
;
174 hl_if
.layout
->api
->speed(hl_if
.handle
, speed
, false);
179 int hl_interface_override_target(const char **targetname
)
181 if (hl_if
.layout
->api
->override_target
) {
182 if (hl_if
.layout
->api
->override_target(*targetname
)) {
183 *targetname
= "hla_target";
191 static int hl_interface_config_trace(bool enabled
, enum tpiu_pin_protocol pin_protocol
,
192 uint32_t port_size
, unsigned int *trace_freq
,
193 unsigned int traceclkin_freq
, uint16_t *prescaler
)
195 if (hl_if
.layout
->api
->config_trace
)
196 return hl_if
.layout
->api
->config_trace(hl_if
.handle
, enabled
,
197 pin_protocol
, port_size
, trace_freq
, traceclkin_freq
, prescaler
);
199 LOG_ERROR("The selected interface does not support tracing");
206 static int hl_interface_poll_trace(uint8_t *buf
, size_t *size
)
208 if (hl_if
.layout
->api
->poll_trace
)
209 return hl_if
.layout
->api
->poll_trace(hl_if
.handle
, buf
, size
);
214 COMMAND_HANDLER(hl_interface_handle_device_desc_command
)
216 LOG_DEBUG("hl_interface_handle_device_desc_command");
219 hl_if
.param
.device_desc
= strdup(CMD_ARGV
[0]);
221 LOG_ERROR("expected exactly one argument to hl_device_desc <description>");
227 COMMAND_HANDLER(hl_interface_handle_serial_command
)
229 LOG_DEBUG("hl_interface_handle_serial_command");
232 hl_if
.param
.serial
= strdup(CMD_ARGV
[0]);
234 LOG_ERROR("expected exactly one argument to hl_serial <serial-number>");
240 COMMAND_HANDLER(hl_interface_handle_layout_command
)
242 LOG_DEBUG("hl_interface_handle_layout_command");
245 LOG_ERROR("Need exactly one argument to stlink_layout");
246 return ERROR_COMMAND_SYNTAX_ERROR
;
250 LOG_ERROR("already specified hl_layout %s",
252 return (strcmp(hl_if
.layout
->name
, CMD_ARGV
[0]) != 0)
253 ? ERROR_FAIL
: ERROR_OK
;
256 for (const struct hl_layout
*l
= hl_layout_get_list(); l
->name
;
258 if (strcmp(l
->name
, CMD_ARGV
[0]) == 0) {
264 LOG_ERROR("No adapter layout '%s' found", CMD_ARGV
[0]);
268 COMMAND_HANDLER(hl_interface_handle_vid_pid_command
)
270 if (CMD_ARGC
> HLA_MAX_USB_IDS
* 2) {
271 LOG_WARNING("ignoring extra IDs in hla_vid_pid "
272 "(maximum is %d pairs)", HLA_MAX_USB_IDS
);
273 CMD_ARGC
= HLA_MAX_USB_IDS
* 2;
275 if (CMD_ARGC
< 2 || (CMD_ARGC
& 1)) {
276 LOG_WARNING("incomplete hla_vid_pid configuration directive");
277 return ERROR_COMMAND_SYNTAX_ERROR
;
281 for (i
= 0; i
< CMD_ARGC
; i
+= 2) {
282 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[i
], hl_if
.param
.vid
[i
/ 2]);
283 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[i
+ 1], hl_if
.param
.pid
[i
/ 2]);
287 * Explicitly terminate, in case there are multiple instances of
290 hl_if
.param
.vid
[i
/ 2] = hl_if
.param
.pid
[i
/ 2] = 0;
295 COMMAND_HANDLER(hl_interface_handle_stlink_backend_command
)
298 bool use_stlink_tcp
= false;
299 uint16_t stlink_tcp_port
= 7184;
301 if (CMD_ARGC
== 0 || CMD_ARGC
> 2)
302 return ERROR_COMMAND_SYNTAX_ERROR
;
303 else if (strcmp(CMD_ARGV
[0], "usb") == 0) {
305 return ERROR_COMMAND_SYNTAX_ERROR
;
306 /* else use_stlink_tcp = false (already the case ) */
307 } else if (strcmp(CMD_ARGV
[0], "tcp") == 0) {
308 use_stlink_tcp
= true;
310 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[1], stlink_tcp_port
);
312 return ERROR_COMMAND_SYNTAX_ERROR
;
314 hl_if
.param
.use_stlink_tcp
= use_stlink_tcp
;
315 hl_if
.param
.stlink_tcp_port
= stlink_tcp_port
;
320 COMMAND_HANDLER(interface_handle_hla_command
)
323 return ERROR_COMMAND_SYNTAX_ERROR
;
325 if (!hl_if
.layout
->api
->custom_command
) {
326 LOG_ERROR("The selected adapter doesn't support custom commands");
330 hl_if
.layout
->api
->custom_command(hl_if
.handle
, CMD_ARGV
[0]);
335 static const struct command_registration hl_interface_command_handlers
[] = {
337 .name
= "hla_device_desc",
338 .handler
= &hl_interface_handle_device_desc_command
,
339 .mode
= COMMAND_CONFIG
,
340 .help
= "set the device description of the adapter",
341 .usage
= "description_string",
344 .name
= "hla_serial",
345 .handler
= &hl_interface_handle_serial_command
,
346 .mode
= COMMAND_CONFIG
,
347 .help
= "set the serial number of the adapter",
348 .usage
= "serial_string",
351 .name
= "hla_layout",
352 .handler
= &hl_interface_handle_layout_command
,
353 .mode
= COMMAND_CONFIG
,
354 .help
= "set the layout of the adapter",
355 .usage
= "layout_name",
358 .name
= "hla_vid_pid",
359 .handler
= &hl_interface_handle_vid_pid_command
,
360 .mode
= COMMAND_CONFIG
,
361 .help
= "the vendor and product ID of the adapter",
362 .usage
= "(vid pid)* ",
365 .name
= "hla_stlink_backend",
366 .handler
= &hl_interface_handle_stlink_backend_command
,
367 .mode
= COMMAND_CONFIG
,
368 .help
= "select which ST-Link backend to use",
369 .usage
= "usb | tcp [port]",
372 .name
= "hla_command",
373 .handler
= &interface_handle_hla_command
,
374 .mode
= COMMAND_EXEC
,
375 .help
= "execute a custom adapter-specific command",
376 .usage
= "<command>",
378 COMMAND_REGISTRATION_DONE
381 struct adapter_driver hl_adapter_driver
= {
383 .transports
= hl_transports
,
384 .commands
= hl_interface_command_handlers
,
386 .init
= hl_interface_init
,
387 .quit
= hl_interface_quit
,
388 .reset
= hl_interface_reset
,
389 .speed
= &hl_interface_speed
,
390 .khz
= &hl_interface_khz
,
391 .speed_div
= &hl_interface_speed_div
,
392 .config_trace
= &hl_interface_config_trace
,
393 .poll_trace
= &hl_interface_poll_trace
,
395 /* no ops for HLA, targets hla_target and stm8 intercept them all */