jtag/adapter: Add command 'adapter gpio'
[openocd.git] / src / jtag / adapter.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>
4 * Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com>
5 * Copyright (C) 2009 SoftPLC Corporation, http://softplc.com, Dick Hollenbeck <dick@softplc.com>
6 * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>
7 * Copyright (C) 2018 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
8 */
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #include "adapter.h"
15 #include "jtag.h"
16 #include "minidriver.h"
17 #include "interface.h"
18 #include "interfaces.h"
19 #include <transport/transport.h>
20
21 #ifdef HAVE_STRINGS_H
22 #include <strings.h>
23 #endif
24
25 /**
26 * @file
27 * Holds support for configuring debug adapters from TCl scripts.
28 */
29
30 struct adapter_driver *adapter_driver;
31 const char * const jtag_only[] = { "jtag", NULL };
32
33 enum adapter_clk_mode {
34 CLOCK_MODE_UNSELECTED = 0,
35 CLOCK_MODE_KHZ,
36 CLOCK_MODE_RCLK
37 };
38
39 #define DEFAULT_CLOCK_SPEED_KHZ 100U
40
41 /**
42 * Adapter configuration
43 */
44 static struct {
45 bool adapter_initialized;
46 char *usb_location;
47 char *serial;
48 enum adapter_clk_mode clock_mode;
49 int speed_khz;
50 int rclk_fallback_speed_khz;
51 struct adapter_gpio_config gpios[ADAPTER_GPIO_IDX_NUM];
52 bool gpios_initialized; /* Initialization of GPIOs to their unset values performed at run time */
53 } adapter_config;
54
55 static const struct gpio_map {
56 const char *name;
57 enum adapter_gpio_direction direction;
58 bool permit_drive_option;
59 bool permit_init_state_option;
60 } gpio_map[ADAPTER_GPIO_IDX_NUM] = {
61 [ADAPTER_GPIO_IDX_TDO] = { "tdo", ADAPTER_GPIO_DIRECTION_INPUT, false, true, },
62 [ADAPTER_GPIO_IDX_TDI] = { "tdi", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
63 [ADAPTER_GPIO_IDX_TMS] = { "tms", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
64 [ADAPTER_GPIO_IDX_TCK] = { "tck", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
65 [ADAPTER_GPIO_IDX_SWDIO] = { "swdio", ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL, true, true, },
66 [ADAPTER_GPIO_IDX_SWDIO_DIR] = { "swdio_dir", ADAPTER_GPIO_DIRECTION_OUTPUT, true, false, },
67 [ADAPTER_GPIO_IDX_SWCLK] = { "swclk", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
68 [ADAPTER_GPIO_IDX_TRST] = { "trst", ADAPTER_GPIO_DIRECTION_OUTPUT, false, true, },
69 [ADAPTER_GPIO_IDX_SRST] = { "srst", ADAPTER_GPIO_DIRECTION_OUTPUT, false, true, },
70 [ADAPTER_GPIO_IDX_LED] = { "led", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },
71 };
72
73 bool is_adapter_initialized(void)
74 {
75 return adapter_config.adapter_initialized;
76 }
77
78 /* For convenience of the bit-banging drivers keep the gpio_config drive
79 * settings for srst and trst in sync with values set by the "adapter
80 * reset_config" command.
81 */
82 static void sync_adapter_reset_with_gpios(void)
83 {
84 enum reset_types cfg = jtag_get_reset_config();
85 if (cfg & RESET_SRST_PUSH_PULL)
86 adapter_config.gpios[ADAPTER_GPIO_IDX_SRST].drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL;
87 else
88 adapter_config.gpios[ADAPTER_GPIO_IDX_SRST].drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN;
89 if (cfg & RESET_TRST_OPEN_DRAIN)
90 adapter_config.gpios[ADAPTER_GPIO_IDX_TRST].drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN;
91 else
92 adapter_config.gpios[ADAPTER_GPIO_IDX_TRST].drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL;
93 }
94
95 static void adapter_driver_gpios_init(void)
96 {
97 if (adapter_config.gpios_initialized)
98 return;
99
100 for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) {
101 adapter_config.gpios[i].gpio_num = -1;
102 adapter_config.gpios[i].chip_num = -1;
103 if (gpio_map[i].direction == ADAPTER_GPIO_DIRECTION_INPUT)
104 adapter_config.gpios[i].init_state = ADAPTER_GPIO_INIT_STATE_INPUT;
105 }
106
107 /* Drivers assume active low, and this is the normal behaviour for reset
108 * lines so should be the default. */
109 adapter_config.gpios[ADAPTER_GPIO_IDX_SRST].active_low = true;
110 adapter_config.gpios[ADAPTER_GPIO_IDX_TRST].active_low = true;
111 sync_adapter_reset_with_gpios();
112
113 /* JTAG GPIOs should be inactive except for tms */
114 adapter_config.gpios[ADAPTER_GPIO_IDX_TMS].init_state = ADAPTER_GPIO_INIT_STATE_ACTIVE;
115
116 adapter_config.gpios_initialized = true;
117 }
118
119 /**
120 * Do low-level setup like initializing registers, output signals,
121 * and clocking.
122 */
123 int adapter_init(struct command_context *cmd_ctx)
124 {
125 if (is_adapter_initialized())
126 return ERROR_OK;
127
128 if (!adapter_driver) {
129 /* nothing was previously specified by "adapter driver" command */
130 LOG_ERROR("Debug Adapter has to be specified, "
131 "see \"adapter driver\" command");
132 return ERROR_JTAG_INVALID_INTERFACE;
133 }
134
135 adapter_driver_gpios_init();
136
137 int retval;
138
139 if (adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) {
140 LOG_WARNING("An adapter speed is not selected in the init scripts."
141 " OpenOCD will try to run the adapter at the low speed (%d kHz)",
142 DEFAULT_CLOCK_SPEED_KHZ);
143 LOG_WARNING("To remove this warnings and achieve reasonable communication speed with the target,"
144 " set \"adapter speed\" or \"jtag_rclk\" in the init scripts.");
145 retval = adapter_config_khz(DEFAULT_CLOCK_SPEED_KHZ);
146 if (retval != ERROR_OK)
147 return ERROR_JTAG_INIT_FAILED;
148 }
149
150 retval = adapter_driver->init();
151 if (retval != ERROR_OK)
152 return retval;
153 adapter_config.adapter_initialized = true;
154
155 if (!adapter_driver->speed) {
156 LOG_INFO("This adapter doesn't support configurable speed");
157 return ERROR_OK;
158 }
159
160 int requested_khz = adapter_get_speed_khz();
161 int actual_khz = requested_khz;
162 int speed_var = 0;
163 retval = adapter_get_speed(&speed_var);
164 if (retval != ERROR_OK)
165 return retval;
166 retval = adapter_driver->speed(speed_var);
167 if (retval != ERROR_OK)
168 return retval;
169 retval = adapter_get_speed_readable(&actual_khz);
170 if (retval != ERROR_OK)
171 LOG_INFO("adapter-specific clock speed value %d", speed_var);
172 else if (actual_khz) {
173 /* Adaptive clocking -- JTAG-specific */
174 if ((adapter_config.clock_mode == CLOCK_MODE_RCLK)
175 || ((adapter_config.clock_mode == CLOCK_MODE_KHZ) && !requested_khz)) {
176 LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz"
177 , actual_khz);
178 } else
179 LOG_INFO("clock speed %d kHz", actual_khz);
180 } else
181 LOG_INFO("RCLK (adaptive clock speed)");
182
183 return ERROR_OK;
184 }
185
186 int adapter_quit(void)
187 {
188 if (is_adapter_initialized() && adapter_driver->quit) {
189 /* close the JTAG interface */
190 int result = adapter_driver->quit();
191 if (result != ERROR_OK)
192 LOG_ERROR("failed: %d", result);
193 }
194
195 free(adapter_config.serial);
196 free(adapter_config.usb_location);
197
198 struct jtag_tap *t = jtag_all_taps();
199 while (t) {
200 struct jtag_tap *n = t->next_tap;
201 jtag_tap_free(t);
202 t = n;
203 }
204
205 return ERROR_OK;
206 }
207
208 unsigned int adapter_get_speed_khz(void)
209 {
210 return adapter_config.speed_khz;
211 }
212
213 static int adapter_khz_to_speed(unsigned int khz, int *speed)
214 {
215 LOG_DEBUG("convert khz to adapter specific speed value");
216 adapter_config.speed_khz = khz;
217 if (!is_adapter_initialized())
218 return ERROR_OK;
219 LOG_DEBUG("have adapter set up");
220 if (!adapter_driver->khz) {
221 LOG_ERROR("Translation from khz to adapter speed not implemented");
222 return ERROR_FAIL;
223 }
224 int speed_div1;
225 int retval = adapter_driver->khz(adapter_get_speed_khz(), &speed_div1);
226 if (retval != ERROR_OK)
227 return retval;
228 *speed = speed_div1;
229 return ERROR_OK;
230 }
231
232 static int adapter_rclk_to_speed(unsigned int fallback_speed_khz, int *speed)
233 {
234 int retval = adapter_khz_to_speed(0, speed);
235 if ((retval != ERROR_OK) && fallback_speed_khz) {
236 LOG_DEBUG("trying fallback speed...");
237 retval = adapter_khz_to_speed(fallback_speed_khz, speed);
238 }
239 return retval;
240 }
241
242 static int adapter_set_speed(int speed)
243 {
244 /* this command can be called during CONFIG,
245 * in which case adapter isn't initialized */
246 return is_adapter_initialized() ? adapter_driver->speed(speed) : ERROR_OK;
247 }
248
249 int adapter_config_khz(unsigned int khz)
250 {
251 LOG_DEBUG("handle adapter khz");
252 adapter_config.clock_mode = CLOCK_MODE_KHZ;
253 int speed = 0;
254 int retval = adapter_khz_to_speed(khz, &speed);
255 return (retval != ERROR_OK) ? retval : adapter_set_speed(speed);
256 }
257
258 int adapter_config_rclk(unsigned int fallback_speed_khz)
259 {
260 LOG_DEBUG("handle adapter rclk");
261 adapter_config.clock_mode = CLOCK_MODE_RCLK;
262 adapter_config.rclk_fallback_speed_khz = fallback_speed_khz;
263 int speed = 0;
264 int retval = adapter_rclk_to_speed(fallback_speed_khz, &speed);
265 return (retval != ERROR_OK) ? retval : adapter_set_speed(speed);
266 }
267
268 int adapter_get_speed(int *speed)
269 {
270 switch (adapter_config.clock_mode) {
271 case CLOCK_MODE_KHZ:
272 adapter_khz_to_speed(adapter_get_speed_khz(), speed);
273 break;
274 case CLOCK_MODE_RCLK:
275 adapter_rclk_to_speed(adapter_config.rclk_fallback_speed_khz, speed);
276 break;
277 default:
278 LOG_ERROR("BUG: unknown adapter clock mode");
279 return ERROR_FAIL;
280 }
281 return ERROR_OK;
282 }
283
284 int adapter_get_speed_readable(int *khz)
285 {
286 int speed_var = 0;
287 int retval = adapter_get_speed(&speed_var);
288 if (retval != ERROR_OK)
289 return retval;
290 if (!is_adapter_initialized())
291 return ERROR_OK;
292 if (!adapter_driver->speed_div) {
293 LOG_ERROR("Translation from adapter speed to khz not implemented");
294 return ERROR_FAIL;
295 }
296 return adapter_driver->speed_div(speed_var, khz);
297 }
298
299 const char *adapter_get_required_serial(void)
300 {
301 return adapter_config.serial;
302 }
303
304 /*
305 * 1 char: bus
306 * 2 * 7 chars: max 7 ports
307 * 1 char: test for overflow
308 * ------
309 * 16 chars
310 */
311 #define USB_MAX_LOCATION_LENGTH 16
312
313 #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
314 static void adapter_usb_set_location(const char *location)
315 {
316 if (strnlen(location, USB_MAX_LOCATION_LENGTH) == USB_MAX_LOCATION_LENGTH)
317 LOG_WARNING("usb location string is too long!!");
318
319 free(adapter_config.usb_location);
320
321 adapter_config.usb_location = strndup(location, USB_MAX_LOCATION_LENGTH);
322 }
323 #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */
324
325 const char *adapter_usb_get_location(void)
326 {
327 return adapter_config.usb_location;
328 }
329
330 bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len)
331 {
332 size_t path_step, string_length;
333 char *ptr, *loc;
334 bool equal = false;
335
336 if (!adapter_usb_get_location())
337 return equal;
338
339 /* strtok need non const char */
340 loc = strndup(adapter_usb_get_location(), USB_MAX_LOCATION_LENGTH);
341 string_length = strnlen(loc, USB_MAX_LOCATION_LENGTH);
342
343 ptr = strtok(loc, "-");
344 if (!ptr) {
345 LOG_WARNING("no '-' in usb path\n");
346 goto done;
347 }
348
349 string_length -= strnlen(ptr, string_length);
350 /* check bus mismatch */
351 if (atoi(ptr) != dev_bus)
352 goto done;
353
354 path_step = 0;
355 while (path_step < path_len) {
356 ptr = strtok(NULL, ".");
357
358 /* no more tokens in path */
359 if (!ptr)
360 break;
361
362 /* path mismatch at some step */
363 if (path_step < path_len && atoi(ptr) != port_path[path_step])
364 break;
365
366 path_step++;
367 string_length -= strnlen(ptr, string_length) + 1;
368 };
369
370 /* walked the full path, all elements match */
371 if (path_step == path_len && !string_length)
372 equal = true;
373
374 done:
375 free(loc);
376 return equal;
377 }
378
379 static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
380 {
381 struct jim_getopt_info goi;
382 jim_getopt_setup(&goi, interp, argc-1, argv + 1);
383
384 /* return the name of the interface */
385 /* TCL code might need to know the exact type... */
386 /* FUTURE: we allow this as a means to "set" the interface. */
387 if (goi.argc != 0) {
388 Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
389 return JIM_ERR;
390 }
391 const char *name = adapter_driver ? adapter_driver->name : NULL;
392 Jim_SetResultString(goi.interp, name ? name : "undefined", -1);
393 return JIM_OK;
394 }
395
396 COMMAND_HANDLER(adapter_transports_command)
397 {
398 char **transports;
399 int retval;
400
401 retval = CALL_COMMAND_HANDLER(transport_list_parse, &transports);
402 if (retval != ERROR_OK)
403 return retval;
404
405 retval = allow_transports(CMD_CTX, (const char **)transports);
406
407 if (retval != ERROR_OK) {
408 for (unsigned i = 0; transports[i]; i++)
409 free(transports[i]);
410 free(transports);
411 }
412 return retval;
413 }
414
415 COMMAND_HANDLER(handle_adapter_list_command)
416 {
417 if (strcmp(CMD_NAME, "list") == 0 && CMD_ARGC > 0)
418 return ERROR_COMMAND_SYNTAX_ERROR;
419
420 command_print(CMD, "The following debug adapters are available:");
421 for (unsigned i = 0; adapter_drivers[i]; i++) {
422 const char *name = adapter_drivers[i]->name;
423 command_print(CMD, "%u: %s", i + 1, name);
424 }
425
426 return ERROR_OK;
427 }
428
429 COMMAND_HANDLER(handle_adapter_driver_command)
430 {
431 int retval;
432
433 /* check whether the interface is already configured */
434 if (adapter_driver) {
435 LOG_WARNING("Interface already configured, ignoring");
436 return ERROR_OK;
437 }
438
439 /* interface name is a mandatory argument */
440 if (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\0')
441 return ERROR_COMMAND_SYNTAX_ERROR;
442
443 for (unsigned i = 0; adapter_drivers[i]; i++) {
444 if (strcmp(CMD_ARGV[0], adapter_drivers[i]->name) != 0)
445 continue;
446
447 if (adapter_drivers[i]->commands) {
448 retval = register_commands(CMD_CTX, NULL, adapter_drivers[i]->commands);
449 if (retval != ERROR_OK)
450 return retval;
451 }
452
453 adapter_driver = adapter_drivers[i];
454
455 return allow_transports(CMD_CTX, adapter_driver->transports);
456 }
457
458 /* no valid interface was found (i.e. the configuration option,
459 * didn't match one of the compiled-in interfaces
460 */
461 LOG_ERROR("The specified debug interface was not found (%s)",
462 CMD_ARGV[0]);
463 CALL_COMMAND_HANDLER(handle_adapter_list_command);
464 return ERROR_JTAG_INVALID_INTERFACE;
465 }
466
467 COMMAND_HANDLER(handle_reset_config_command)
468 {
469 int new_cfg = 0;
470 int mask = 0;
471
472 /* Original versions cared about the order of these tokens:
473 * reset_config signals [combination [trst_type [srst_type]]]
474 * They also clobbered the previous configuration even on error.
475 *
476 * Here we don't care about the order, and only change values
477 * which have been explicitly specified.
478 */
479 for (; CMD_ARGC; CMD_ARGC--, CMD_ARGV++) {
480 int tmp = 0;
481 int m;
482
483 /* gating */
484 m = RESET_SRST_NO_GATING;
485 if (strcmp(*CMD_ARGV, "srst_gates_jtag") == 0)
486 /* default: don't use JTAG while SRST asserted */;
487 else if (strcmp(*CMD_ARGV, "srst_nogate") == 0)
488 tmp = RESET_SRST_NO_GATING;
489 else
490 m = 0;
491 if (mask & m) {
492 LOG_ERROR("extra reset_config %s spec (%s)",
493 "gating", *CMD_ARGV);
494 return ERROR_COMMAND_SYNTAX_ERROR;
495 }
496 if (m)
497 goto next;
498
499 /* signals */
500 m = RESET_HAS_TRST | RESET_HAS_SRST;
501 if (strcmp(*CMD_ARGV, "none") == 0)
502 tmp = RESET_NONE;
503 else if (strcmp(*CMD_ARGV, "trst_only") == 0)
504 tmp = RESET_HAS_TRST;
505 else if (strcmp(*CMD_ARGV, "srst_only") == 0)
506 tmp = RESET_HAS_SRST;
507 else if (strcmp(*CMD_ARGV, "trst_and_srst") == 0)
508 tmp = RESET_HAS_TRST | RESET_HAS_SRST;
509 else
510 m = 0;
511 if (mask & m) {
512 LOG_ERROR("extra reset_config %s spec (%s)",
513 "signal", *CMD_ARGV);
514 return ERROR_COMMAND_SYNTAX_ERROR;
515 }
516 if (m)
517 goto next;
518
519 /* combination (options for broken wiring) */
520 m = RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;
521 if (strcmp(*CMD_ARGV, "separate") == 0)
522 /* separate reset lines - default */;
523 else if (strcmp(*CMD_ARGV, "srst_pulls_trst") == 0)
524 tmp |= RESET_SRST_PULLS_TRST;
525 else if (strcmp(*CMD_ARGV, "trst_pulls_srst") == 0)
526 tmp |= RESET_TRST_PULLS_SRST;
527 else if (strcmp(*CMD_ARGV, "combined") == 0)
528 tmp |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;
529 else
530 m = 0;
531 if (mask & m) {
532 LOG_ERROR("extra reset_config %s spec (%s)",
533 "combination", *CMD_ARGV);
534 return ERROR_COMMAND_SYNTAX_ERROR;
535 }
536 if (m)
537 goto next;
538
539 /* trst_type (NOP without HAS_TRST) */
540 m = RESET_TRST_OPEN_DRAIN;
541 if (strcmp(*CMD_ARGV, "trst_open_drain") == 0)
542 tmp |= RESET_TRST_OPEN_DRAIN;
543 else if (strcmp(*CMD_ARGV, "trst_push_pull") == 0)
544 /* push/pull from adapter - default */;
545 else
546 m = 0;
547 if (mask & m) {
548 LOG_ERROR("extra reset_config %s spec (%s)",
549 "trst_type", *CMD_ARGV);
550 return ERROR_COMMAND_SYNTAX_ERROR;
551 }
552 if (m)
553 goto next;
554
555 /* srst_type (NOP without HAS_SRST) */
556 m = RESET_SRST_PUSH_PULL;
557 if (strcmp(*CMD_ARGV, "srst_push_pull") == 0)
558 tmp |= RESET_SRST_PUSH_PULL;
559 else if (strcmp(*CMD_ARGV, "srst_open_drain") == 0)
560 /* open drain from adapter - default */;
561 else
562 m = 0;
563 if (mask & m) {
564 LOG_ERROR("extra reset_config %s spec (%s)",
565 "srst_type", *CMD_ARGV);
566 return ERROR_COMMAND_SYNTAX_ERROR;
567 }
568 if (m)
569 goto next;
570
571 /* connect_type - only valid when srst_nogate */
572 m = RESET_CNCT_UNDER_SRST;
573 if (strcmp(*CMD_ARGV, "connect_assert_srst") == 0)
574 tmp |= RESET_CNCT_UNDER_SRST;
575 else if (strcmp(*CMD_ARGV, "connect_deassert_srst") == 0)
576 /* connect normally - default */;
577 else
578 m = 0;
579 if (mask & m) {
580 LOG_ERROR("extra reset_config %s spec (%s)",
581 "connect_type", *CMD_ARGV);
582 return ERROR_COMMAND_SYNTAX_ERROR;
583 }
584 if (m)
585 goto next;
586
587 /* caller provided nonsense; fail */
588 LOG_ERROR("unknown reset_config flag (%s)", *CMD_ARGV);
589 return ERROR_COMMAND_SYNTAX_ERROR;
590
591 next:
592 /* Remember the bits which were specified (mask)
593 * and their new values (new_cfg).
594 */
595 mask |= m;
596 new_cfg |= tmp;
597 }
598
599 /* clear previous values of those bits, save new values */
600 if (mask) {
601 int old_cfg = jtag_get_reset_config();
602
603 old_cfg &= ~mask;
604 new_cfg |= old_cfg;
605 jtag_set_reset_config(new_cfg);
606 sync_adapter_reset_with_gpios();
607
608 } else
609 new_cfg = jtag_get_reset_config();
610
611 /*
612 * Display the (now-)current reset mode
613 */
614 char *modes[6];
615
616 /* minimal JTAG has neither SRST nor TRST (so that's the default) */
617 switch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) {
618 case RESET_HAS_SRST:
619 modes[0] = "srst_only";
620 break;
621 case RESET_HAS_TRST:
622 modes[0] = "trst_only";
623 break;
624 case RESET_TRST_AND_SRST:
625 modes[0] = "trst_and_srst";
626 break;
627 default:
628 modes[0] = "none";
629 break;
630 }
631
632 /* normally SRST and TRST are decoupled; but bugs happen ... */
633 switch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) {
634 case RESET_SRST_PULLS_TRST:
635 modes[1] = "srst_pulls_trst";
636 break;
637 case RESET_TRST_PULLS_SRST:
638 modes[1] = "trst_pulls_srst";
639 break;
640 case RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST:
641 modes[1] = "combined";
642 break;
643 default:
644 modes[1] = "separate";
645 break;
646 }
647
648 /* TRST-less connectors include Altera, Xilinx, and minimal JTAG */
649 if (new_cfg & RESET_HAS_TRST) {
650 if (new_cfg & RESET_TRST_OPEN_DRAIN)
651 modes[3] = " trst_open_drain";
652 else
653 modes[3] = " trst_push_pull";
654 } else
655 modes[3] = "";
656
657 /* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */
658 if (new_cfg & RESET_HAS_SRST) {
659 if (new_cfg & RESET_SRST_NO_GATING)
660 modes[2] = " srst_nogate";
661 else
662 modes[2] = " srst_gates_jtag";
663
664 if (new_cfg & RESET_SRST_PUSH_PULL)
665 modes[4] = " srst_push_pull";
666 else
667 modes[4] = " srst_open_drain";
668
669 if (new_cfg & RESET_CNCT_UNDER_SRST)
670 modes[5] = " connect_assert_srst";
671 else
672 modes[5] = " connect_deassert_srst";
673 } else {
674 modes[2] = "";
675 modes[4] = "";
676 modes[5] = "";
677 }
678
679 command_print(CMD, "%s %s%s%s%s%s",
680 modes[0], modes[1],
681 modes[2], modes[3], modes[4], modes[5]);
682
683 return ERROR_OK;
684 }
685
686 COMMAND_HANDLER(handle_adapter_srst_delay_command)
687 {
688 if (CMD_ARGC > 1)
689 return ERROR_COMMAND_SYNTAX_ERROR;
690 if (CMD_ARGC == 1) {
691 unsigned delay;
692 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);
693
694 jtag_set_nsrst_delay(delay);
695 }
696 command_print(CMD, "adapter srst delay: %u", jtag_get_nsrst_delay());
697 return ERROR_OK;
698 }
699
700 COMMAND_HANDLER(handle_adapter_srst_pulse_width_command)
701 {
702 if (CMD_ARGC > 1)
703 return ERROR_COMMAND_SYNTAX_ERROR;
704 if (CMD_ARGC == 1) {
705 unsigned width;
706 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], width);
707
708 jtag_set_nsrst_assert_width(width);
709 }
710 command_print(CMD, "adapter srst pulse_width: %u", jtag_get_nsrst_assert_width());
711 return ERROR_OK;
712 }
713
714 COMMAND_HANDLER(handle_adapter_speed_command)
715 {
716 if (CMD_ARGC > 1)
717 return ERROR_COMMAND_SYNTAX_ERROR;
718
719 int retval = ERROR_OK;
720 if (CMD_ARGC == 1) {
721 unsigned khz = 0;
722 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);
723
724 retval = adapter_config_khz(khz);
725 if (retval != ERROR_OK)
726 return retval;
727 }
728
729 int cur_speed = adapter_get_speed_khz();
730 retval = adapter_get_speed_readable(&cur_speed);
731 if (retval != ERROR_OK)
732 return retval;
733
734 if (cur_speed)
735 command_print(CMD, "adapter speed: %d kHz", cur_speed);
736 else
737 command_print(CMD, "adapter speed: RCLK - adaptive");
738
739 return retval;
740 }
741
742 COMMAND_HANDLER(handle_adapter_serial_command)
743 {
744 if (CMD_ARGC != 1)
745 return ERROR_COMMAND_SYNTAX_ERROR;
746
747 free(adapter_config.serial);
748 adapter_config.serial = strdup(CMD_ARGV[0]);
749 return ERROR_OK;
750 }
751
752 COMMAND_HANDLER(handle_adapter_reset_de_assert)
753 {
754 enum values {
755 VALUE_UNDEFINED = -1,
756 VALUE_DEASSERT = 0,
757 VALUE_ASSERT = 1,
758 };
759 enum values value;
760 enum values srst = VALUE_UNDEFINED;
761 enum values trst = VALUE_UNDEFINED;
762 enum reset_types jtag_reset_config = jtag_get_reset_config();
763 char *signal;
764
765 if (CMD_ARGC == 0) {
766 if (transport_is_jtag()) {
767 if (jtag_reset_config & RESET_HAS_TRST)
768 signal = jtag_get_trst() ? "asserted" : "deasserted";
769 else
770 signal = "not present";
771 command_print(CMD, "trst %s", signal);
772 }
773
774 if (jtag_reset_config & RESET_HAS_SRST)
775 signal = jtag_get_srst() ? "asserted" : "deasserted";
776 else
777 signal = "not present";
778 command_print(CMD, "srst %s", signal);
779
780 return ERROR_OK;
781 }
782
783 if (CMD_ARGC != 1 && CMD_ARGC != 3)
784 return ERROR_COMMAND_SYNTAX_ERROR;
785
786 value = (strcmp(CMD_NAME, "assert") == 0) ? VALUE_ASSERT : VALUE_DEASSERT;
787 if (strcmp(CMD_ARGV[0], "srst") == 0)
788 srst = value;
789 else if (strcmp(CMD_ARGV[0], "trst") == 0)
790 trst = value;
791 else
792 return ERROR_COMMAND_SYNTAX_ERROR;
793
794 if (CMD_ARGC == 3) {
795 if (strcmp(CMD_ARGV[1], "assert") == 0)
796 value = VALUE_ASSERT;
797 else if (strcmp(CMD_ARGV[1], "deassert") == 0)
798 value = VALUE_DEASSERT;
799 else
800 return ERROR_COMMAND_SYNTAX_ERROR;
801
802 if (strcmp(CMD_ARGV[2], "srst") == 0 && srst == VALUE_UNDEFINED)
803 srst = value;
804 else if (strcmp(CMD_ARGV[2], "trst") == 0 && trst == VALUE_UNDEFINED)
805 trst = value;
806 else
807 return ERROR_COMMAND_SYNTAX_ERROR;
808 }
809
810 if (trst == VALUE_UNDEFINED) {
811 if (transport_is_jtag())
812 trst = jtag_get_trst() ? VALUE_ASSERT : VALUE_DEASSERT;
813 else
814 trst = VALUE_DEASSERT; /* unused, safe value */
815 }
816
817 if (srst == VALUE_UNDEFINED) {
818 if (jtag_reset_config & RESET_HAS_SRST)
819 srst = jtag_get_srst() ? VALUE_ASSERT : VALUE_DEASSERT;
820 else
821 srst = VALUE_DEASSERT; /* unused, safe value */
822 }
823
824 if (trst == VALUE_ASSERT && !transport_is_jtag()) {
825 LOG_ERROR("transport has no trst signal");
826 return ERROR_FAIL;
827 }
828
829 if (srst == VALUE_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
830 LOG_ERROR("adapter has no srst signal");
831 return ERROR_FAIL;
832 }
833
834 return adapter_resets((trst == VALUE_DEASSERT) ? TRST_DEASSERT : TRST_ASSERT,
835 (srst == VALUE_DEASSERT) ? SRST_DEASSERT : SRST_ASSERT);
836 }
837
838 static int get_gpio_index(const char *signal_name)
839 {
840 for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) {
841 if (strcmp(gpio_map[i].name, signal_name) == 0)
842 return i;
843 }
844 return -1;
845 }
846
847 COMMAND_HELPER(helper_adapter_gpio_print_config, enum adapter_gpio_config_index gpio_idx)
848 {
849 struct adapter_gpio_config *gpio_config = &adapter_config.gpios[gpio_idx];
850 const char *active_state = gpio_config->active_low ? "low" : "high";
851 const char *dir = "";
852 const char *drive = "";
853 const char *pull = "";
854 const char *init_state = "";
855
856 switch (gpio_map[gpio_idx].direction) {
857 case ADAPTER_GPIO_DIRECTION_INPUT:
858 dir = "input";
859 break;
860 case ADAPTER_GPIO_DIRECTION_OUTPUT:
861 dir = "output";
862 break;
863 case ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL:
864 dir = "bidirectional";
865 break;
866 }
867
868 if (gpio_map[gpio_idx].permit_drive_option) {
869 switch (gpio_config->drive) {
870 case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:
871 drive = ", push-pull";
872 break;
873 case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:
874 drive = ", open-drain";
875 break;
876 case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
877 drive = ", open-source";
878 break;
879 }
880 }
881
882 switch (gpio_config->pull) {
883 case ADAPTER_GPIO_PULL_NONE:
884 pull = ", pull-none";
885 break;
886 case ADAPTER_GPIO_PULL_UP:
887 pull = ", pull-up";
888 break;
889 case ADAPTER_GPIO_PULL_DOWN:
890 pull = ", pull-down";
891 break;
892 }
893
894 if (gpio_map[gpio_idx].permit_init_state_option) {
895 switch (gpio_config->init_state) {
896 case ADAPTER_GPIO_INIT_STATE_INACTIVE:
897 init_state = ", init-state inactive";
898 break;
899 case ADAPTER_GPIO_INIT_STATE_ACTIVE:
900 init_state = ", init-state active";
901 break;
902 case ADAPTER_GPIO_INIT_STATE_INPUT:
903 init_state = ", init-state input";
904 break;
905 }
906 }
907
908 command_print(CMD, "adapter gpio %s (%s): num %d, chip %d, active-%s%s%s%s",
909 gpio_map[gpio_idx].name, dir, gpio_config->gpio_num, gpio_config->chip_num, active_state,
910 drive, pull, init_state);
911
912 return ERROR_OK;
913 }
914
915 COMMAND_HANDLER(helper_adapter_gpio_print_all_configs)
916 {
917 for (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i)
918 CALL_COMMAND_HANDLER(helper_adapter_gpio_print_config, i);
919 return ERROR_OK;
920 }
921
922 COMMAND_HANDLER(adapter_gpio_config_handler)
923 {
924 unsigned int i = 1;
925 struct adapter_gpio_config *gpio_config;
926
927 adapter_driver_gpios_init();
928
929 if (CMD_ARGC == 0) {
930 CALL_COMMAND_HANDLER(helper_adapter_gpio_print_all_configs);
931 return ERROR_OK;
932 }
933
934 int gpio_idx = get_gpio_index(CMD_ARGV[0]);
935 if (gpio_idx == -1) {
936 LOG_ERROR("adapter has no gpio named %s", CMD_ARGV[0]);
937 return ERROR_COMMAND_SYNTAX_ERROR;
938 }
939
940 if (CMD_ARGC == 1) {
941 CALL_COMMAND_HANDLER(helper_adapter_gpio_print_config, gpio_idx);
942 return ERROR_OK;
943 }
944
945 gpio_config = &adapter_config.gpios[gpio_idx];
946 while (i < CMD_ARGC) {
947 LOG_DEBUG("Processing %s", CMD_ARGV[i]);
948
949 if (isdigit(*CMD_ARGV[i])) {
950 int gpio_num; /* Use a meaningful output parameter for more helpful error messages */
951 COMMAND_PARSE_NUMBER(int, CMD_ARGV[i], gpio_num);
952 gpio_config->gpio_num = gpio_num;
953 ++i;
954 continue;
955 }
956
957 if (strcmp(CMD_ARGV[i], "-chip") == 0) {
958 if (CMD_ARGC - i < 2) {
959 LOG_ERROR("-chip option requires a parameter");
960 return ERROR_FAIL;
961 }
962 LOG_DEBUG("-chip arg is %s", CMD_ARGV[i + 1]);
963 int chip_num; /* Use a meaningful output parameter for more helpful error messages */
964 COMMAND_PARSE_NUMBER(int, CMD_ARGV[i + 1], chip_num);
965 gpio_config->chip_num = chip_num;
966 i += 2;
967 continue;
968 }
969
970 if (strcmp(CMD_ARGV[i], "-active-high") == 0) {
971 ++i;
972 gpio_config->active_low = false;
973 continue;
974 }
975 if (strcmp(CMD_ARGV[i], "-active-low") == 0) {
976 ++i;
977 gpio_config->active_low = true;
978 continue;
979 }
980
981 if (gpio_map[gpio_idx].permit_drive_option) {
982 if (strcmp(CMD_ARGV[i], "-push-pull") == 0) {
983 ++i;
984 gpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL;
985 continue;
986 }
987 if (strcmp(CMD_ARGV[i], "-open-drain") == 0) {
988 ++i;
989 gpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN;
990 continue;
991 }
992 if (strcmp(CMD_ARGV[i], "-open-source") == 0) {
993 ++i;
994 gpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE;
995 continue;
996 }
997 }
998
999 if (strcmp(CMD_ARGV[i], "-pull-none") == 0) {
1000 ++i;
1001 gpio_config->pull = ADAPTER_GPIO_PULL_NONE;
1002 continue;
1003 }
1004 if (strcmp(CMD_ARGV[i], "-pull-up") == 0) {
1005 ++i;
1006 gpio_config->pull = ADAPTER_GPIO_PULL_UP;
1007 continue;
1008 }
1009 if (strcmp(CMD_ARGV[i], "-pull-down") == 0) {
1010 ++i;
1011 gpio_config->pull = ADAPTER_GPIO_PULL_DOWN;
1012 continue;
1013 }
1014
1015 if (gpio_map[gpio_idx].permit_init_state_option) {
1016 if (strcmp(CMD_ARGV[i], "-init-inactive") == 0) {
1017 ++i;
1018 gpio_config->init_state = ADAPTER_GPIO_INIT_STATE_INACTIVE;
1019 continue;
1020 }
1021 if (strcmp(CMD_ARGV[i], "-init-active") == 0) {
1022 ++i;
1023 gpio_config->init_state = ADAPTER_GPIO_INIT_STATE_ACTIVE;
1024 continue;
1025 }
1026
1027 if (gpio_map[gpio_idx].direction == ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL &&
1028 strcmp(CMD_ARGV[i], "-init-input") == 0) {
1029 ++i;
1030 gpio_config->init_state = ADAPTER_GPIO_INIT_STATE_INPUT;
1031 continue;
1032 }
1033 }
1034
1035 LOG_ERROR("illegal option for adapter %s %s: %s",
1036 CMD_NAME, gpio_map[gpio_idx].name, CMD_ARGV[i]);
1037 return ERROR_COMMAND_SYNTAX_ERROR;
1038 }
1039
1040 /* Force swdio_dir init state to be compatible with swdio init state */
1041 if (gpio_idx == ADAPTER_GPIO_IDX_SWDIO)
1042 adapter_config.gpios[ADAPTER_GPIO_IDX_SWDIO_DIR].init_state =
1043 (gpio_config->init_state == ADAPTER_GPIO_INIT_STATE_INPUT) ?
1044 ADAPTER_GPIO_INIT_STATE_INACTIVE :
1045 ADAPTER_GPIO_INIT_STATE_ACTIVE;
1046
1047 return ERROR_OK;
1048 }
1049
1050 #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
1051 COMMAND_HANDLER(handle_usb_location_command)
1052 {
1053 if (CMD_ARGC == 1)
1054 adapter_usb_set_location(CMD_ARGV[0]);
1055
1056 command_print(CMD, "adapter usb location: %s", adapter_usb_get_location());
1057
1058 return ERROR_OK;
1059 }
1060 #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */
1061
1062 static const struct command_registration adapter_usb_command_handlers[] = {
1063 #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
1064 {
1065 .name = "location",
1066 .handler = &handle_usb_location_command,
1067 .mode = COMMAND_CONFIG,
1068 .help = "display or set the USB bus location of the USB device",
1069 .usage = "[<bus>-port[.port]...]",
1070 },
1071 #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */
1072 COMMAND_REGISTRATION_DONE
1073 };
1074
1075 static const struct command_registration adapter_srst_command_handlers[] = {
1076 {
1077 .name = "delay",
1078 .handler = handle_adapter_srst_delay_command,
1079 .mode = COMMAND_ANY,
1080 .help = "delay after deasserting SRST in ms",
1081 .usage = "[milliseconds]",
1082 },
1083 {
1084 .name = "pulse_width",
1085 .handler = handle_adapter_srst_pulse_width_command,
1086 .mode = COMMAND_ANY,
1087 .help = "SRST assertion pulse width in ms",
1088 .usage = "[milliseconds]",
1089 },
1090 COMMAND_REGISTRATION_DONE
1091 };
1092
1093 static const struct command_registration adapter_command_handlers[] = {
1094 {
1095 .name = "driver",
1096 .handler = handle_adapter_driver_command,
1097 .mode = COMMAND_CONFIG,
1098 .help = "Select a debug adapter driver",
1099 .usage = "driver_name",
1100 },
1101 {
1102 .name = "speed",
1103 .handler = handle_adapter_speed_command,
1104 .mode = COMMAND_ANY,
1105 .help = "With an argument, change to the specified maximum "
1106 "jtag speed. For JTAG, 0 KHz signifies adaptive "
1107 "clocking. "
1108 "With or without argument, display current setting.",
1109 .usage = "[khz]",
1110 },
1111 {
1112 .name = "serial",
1113 .handler = handle_adapter_serial_command,
1114 .mode = COMMAND_CONFIG,
1115 .help = "Set the serial number of the adapter",
1116 .usage = "serial_string",
1117 },
1118 {
1119 .name = "list",
1120 .handler = handle_adapter_list_command,
1121 .mode = COMMAND_ANY,
1122 .help = "List all built-in debug adapter drivers",
1123 .usage = "",
1124 },
1125 {
1126 .name = "name",
1127 .mode = COMMAND_ANY,
1128 .jim_handler = jim_adapter_name,
1129 .help = "Returns the name of the currently "
1130 "selected adapter (driver)",
1131 },
1132 {
1133 .name = "srst",
1134 .mode = COMMAND_ANY,
1135 .help = "srst adapter command group",
1136 .usage = "",
1137 .chain = adapter_srst_command_handlers,
1138 },
1139 {
1140 .name = "transports",
1141 .handler = adapter_transports_command,
1142 .mode = COMMAND_CONFIG,
1143 .help = "Declare transports the adapter supports.",
1144 .usage = "transport ...",
1145 },
1146 {
1147 .name = "usb",
1148 .mode = COMMAND_ANY,
1149 .help = "usb adapter command group",
1150 .usage = "",
1151 .chain = adapter_usb_command_handlers,
1152 },
1153 {
1154 .name = "assert",
1155 .handler = handle_adapter_reset_de_assert,
1156 .mode = COMMAND_EXEC,
1157 .help = "Controls SRST and TRST lines.",
1158 .usage = "|deassert [srst|trst [assert|deassert srst|trst]]",
1159 },
1160 {
1161 .name = "deassert",
1162 .handler = handle_adapter_reset_de_assert,
1163 .mode = COMMAND_EXEC,
1164 .help = "Controls SRST and TRST lines.",
1165 .usage = "|assert [srst|trst [deassert|assert srst|trst]]",
1166 },
1167 {
1168 .name = "gpio",
1169 .handler = adapter_gpio_config_handler,
1170 .mode = COMMAND_CONFIG,
1171 .help = "gpio adapter command group",
1172 .usage = "[ tdo|tdi|tms|tck|trst|swdio|swdio_dir|swclk|srst|led"
1173 "[gpio_number] "
1174 "[-chip chip_number] "
1175 "[-active-high|-active-low] "
1176 "[-push-pull|-open-drain|-open-source] "
1177 "[-pull-none|-pull-up|-pull-down]"
1178 "[-init-inactive|-init-active|-init-input] ]",
1179 },
1180 COMMAND_REGISTRATION_DONE
1181 };
1182
1183 static const struct command_registration interface_command_handlers[] = {
1184 {
1185 .name = "adapter",
1186 .mode = COMMAND_ANY,
1187 .help = "adapter command group",
1188 .usage = "",
1189 .chain = adapter_command_handlers,
1190 },
1191 {
1192 .name = "reset_config",
1193 .handler = handle_reset_config_command,
1194 .mode = COMMAND_ANY,
1195 .help = "configure adapter reset behavior",
1196 .usage = "[none|trst_only|srst_only|trst_and_srst] "
1197 "[srst_pulls_trst|trst_pulls_srst|combined|separate] "
1198 "[srst_gates_jtag|srst_nogate] "
1199 "[trst_push_pull|trst_open_drain] "
1200 "[srst_push_pull|srst_open_drain] "
1201 "[connect_deassert_srst|connect_assert_srst]",
1202 },
1203 COMMAND_REGISTRATION_DONE
1204 };
1205
1206 /**
1207 * Register the commands which deal with arbitrary debug adapter drivers.
1208 *
1209 * @todo Remove internal assumptions that all debug adapters use JTAG for
1210 * transport. Various types and data structures are not named generically.
1211 */
1212 int adapter_register_commands(struct command_context *ctx)
1213 {
1214 return register_commands(ctx, NULL, interface_command_handlers);
1215 }
1216
1217 const char *adapter_gpio_get_name(enum adapter_gpio_config_index idx)
1218 {
1219 return gpio_map[idx].name;
1220 }
1221
1222 /* Allow drivers access to the GPIO configuration */
1223 const struct adapter_gpio_config *adapter_gpio_get_config(void)
1224 {
1225 return adapter_config.gpios;
1226 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)