adapter: add command "adapter [de]assert srst|trst [[de]assert srst|trst]"

Inspired from http://openocd.zylin.com/#/c/3720/1

Add commands to control the adapter's signals srst and trst.
Add macros for the flag's values assert/deassert to make clear what
they mean and to propose a uniform set of values across the code.

Change-Id: Ia8b13f4ded892942916cad7bda49540a896e7218
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/5277
Tested-by: jenkins
This commit is contained in:
Antonio Borneo 2019-01-10 10:58:15 +01:00 committed by Tomas Vanek
parent deff24afa1
commit fafe6dfc9c
6 changed files with 186 additions and 0 deletions

View File

@ -411,6 +411,92 @@ COMMAND_HANDLER(handle_adapter_khz_command)
return retval;
}
COMMAND_HANDLER(handle_adapter_reset_de_assert)
{
enum values {
VALUE_UNDEFINED = -1,
VALUE_DEASSERT = 0,
VALUE_ASSERT = 1,
};
enum values value;
enum values srst = VALUE_UNDEFINED;
enum values trst = VALUE_UNDEFINED;
enum reset_types jtag_reset_config = jtag_get_reset_config();
char *signal;
if (CMD_ARGC == 0) {
if (transport_is_jtag()) {
if (jtag_reset_config & RESET_HAS_TRST)
signal = jtag_get_trst() ? "asserted" : "deasserted";
else
signal = "not present";
command_print(CMD, "trst %s", signal);
}
if (jtag_reset_config & RESET_HAS_SRST)
signal = jtag_get_srst() ? "asserted" : "deasserted";
else
signal = "not present";
command_print(CMD, "srst %s", signal);
return ERROR_OK;
}
if (CMD_ARGC != 1 && CMD_ARGC != 3)
return ERROR_COMMAND_SYNTAX_ERROR;
value = (strcmp(CMD_NAME, "assert") == 0) ? VALUE_ASSERT : VALUE_DEASSERT;
if (strcmp(CMD_ARGV[0], "srst") == 0)
srst = value;
else if (strcmp(CMD_ARGV[0], "trst") == 0)
trst = value;
else
return ERROR_COMMAND_SYNTAX_ERROR;
if (CMD_ARGC == 3) {
if (strcmp(CMD_ARGV[1], "assert") == 0)
value = VALUE_ASSERT;
else if (strcmp(CMD_ARGV[1], "deassert") == 0)
value = VALUE_DEASSERT;
else
return ERROR_COMMAND_SYNTAX_ERROR;
if (strcmp(CMD_ARGV[2], "srst") == 0 && srst == VALUE_UNDEFINED)
srst = value;
else if (strcmp(CMD_ARGV[2], "trst") == 0 && trst == VALUE_UNDEFINED)
trst = value;
else
return ERROR_COMMAND_SYNTAX_ERROR;
}
if (trst == VALUE_UNDEFINED) {
if (transport_is_jtag())
trst = jtag_get_trst() ? VALUE_ASSERT : VALUE_DEASSERT;
else
trst = VALUE_DEASSERT; /* unused, safe value */
}
if (srst == VALUE_UNDEFINED) {
if (jtag_reset_config & RESET_HAS_SRST)
srst = jtag_get_srst() ? VALUE_ASSERT : VALUE_DEASSERT;
else
srst = VALUE_DEASSERT; /* unused, safe value */
}
if (trst == VALUE_ASSERT && !transport_is_jtag()) {
LOG_ERROR("transport has no trst signal");
return ERROR_FAIL;
}
if (srst == VALUE_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
LOG_ERROR("adapter has no srst signal");
return ERROR_FAIL;
}
return adapter_resets((trst == VALUE_DEASSERT) ? TRST_DEASSERT : TRST_ASSERT,
(srst == VALUE_DEASSERT) ? SRST_DEASSERT : SRST_ASSERT);
}
#ifndef HAVE_JTAG_MINIDRIVER_H
#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
COMMAND_HANDLER(handle_usb_location_command)
@ -448,6 +534,20 @@ static const struct command_registration adapter_command_handlers[] = {
.chain = adapter_usb_command_handlers,
},
#endif /* MINIDRIVER */
{
.name = "assert",
.handler = handle_adapter_reset_de_assert,
.mode = COMMAND_EXEC,
.help = "Controls SRST and TRST lines.",
.usage = "|deassert [srst|trst [assert|deassert srst|trst]]",
},
{
.name = "deassert",
.handler = handle_adapter_reset_de_assert,
.mode = COMMAND_EXEC,
.help = "Controls SRST and TRST lines.",
.usage = "|assert [srst|trst [deassert|assert srst|trst]]",
},
COMMAND_REGISTRATION_DONE
};

View File

@ -35,6 +35,8 @@
#include "interface.h"
#include <transport/transport.h>
#include <helper/jep106.h>
#include <jtag/hla/hla_transport.h>
#include <jtag/hla/hla_interface.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
@ -1888,6 +1890,57 @@ bool transport_is_jtag(void)
return get_current_transport() == &jtag_transport;
}
int adapter_resets(int trst, int srst)
{
if (get_current_transport() == NULL) {
LOG_ERROR("transport is not selected");
return ERROR_FAIL;
}
if (transport_is_jtag()) {
if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
LOG_ERROR("adapter has no srst signal");
return ERROR_FAIL;
}
/* adapters without trst signal will eventually use tlr sequence */
jtag_add_reset(trst, srst);
return ERROR_OK;
} else if (transport_is_swd()) {
if (trst == TRST_ASSERT) {
LOG_ERROR("transport swd has no trst signal");
return ERROR_FAIL;
}
if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
LOG_ERROR("adapter has no srst signal");
return ERROR_FAIL;
}
swd_add_reset(srst);
return ERROR_OK;
} else if (transport_is_hla()) {
if (trst == TRST_ASSERT) {
LOG_ERROR("transport %s has no trst signal",
get_current_transport()->name);
return ERROR_FAIL;
}
if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
LOG_ERROR("adapter has no srst signal");
return ERROR_FAIL;
}
return hl_interface_reset(srst);
}
if (trst == TRST_DEASSERT && srst == SRST_DEASSERT)
return ERROR_OK;
LOG_ERROR("reset is not supported on transport %s",
get_current_transport()->name);
return ERROR_FAIL;
}
void adapter_assert_reset(void)
{
if (transport_is_jtag()) {

View File

@ -148,6 +148,21 @@ int hl_interface_init_reset(void)
return ERROR_OK;
}
/* FIXME: hla abuses of jtag_add_reset() to track srst status and for timings */
int hl_interface_reset(int srst)
{
int result;
if (srst == 1) {
jtag_add_reset(0, 1);
result = hl_if.layout->api->assert_srst(hl_if.handle, 0);
} else {
result = hl_if.layout->api->assert_srst(hl_if.handle, 1);
jtag_add_reset(0, 0);
}
return result;
}
static int hl_interface_khz(int khz, int *jtag_speed)
{
if (hl_if.layout->api->speed == NULL)

View File

@ -67,4 +67,13 @@ int hl_interface_init_target(struct target *t);
int hl_interface_init_reset(void);
int hl_interface_override_target(const char **targetname);
#if BUILD_HLADAPTER == 1
int hl_interface_reset(int srst);
#else
static inline int hl_interface_reset(int srst)
{
return ERROR_OK;
}
#endif
#endif /* OPENOCD_JTAG_HLA_HLA_INTERFACE_H */

View File

@ -326,6 +326,7 @@ struct jtag_interface {
extern const char * const jtag_only[];
int adapter_resets(int assert_trst, int assert_srst);
void adapter_assert_reset(void);
void adapter_deassert_reset(void);
int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,

View File

@ -76,6 +76,14 @@ typedef enum tap_state {
#endif
} tap_state_t;
/**
* Defines arguments for reset functions
*/
#define SRST_DEASSERT 0
#define SRST_ASSERT 1
#define TRST_DEASSERT 0
#define TRST_ASSERT 1
/**
* Function tap_state_name
* Returns a string suitable for display representing the JTAG tap_state