swd: get rid of jtag queue to assert/deassert srst

The transport SWD uses the JTAG queue to assert/deassert the
system reset srst. This is the major inconsistency that has to be
removed to properly split JTAG and SWD.

Introduce a new driver API, reset(), to controls both the signals
trst and srst in the driver, skipping the JTAG queue. Put the new
API in struct jtag_interface, even if in this patch it's used for
SWD only; the goal is to get it reused by the other transports.

Add the implementation of the API in all the drivers that
implement SWD. Such implementation is almost the same of the old
code in JTAG queue.

Create a wrapper adapter_system_reset() to use the new API and
remove the SWD specific swd_add_reset(). In the wrapper replace
jtag_add_sleep() with jtag_sleep(), because the former uses the
JTAG queue too.
Rename the old jtag_add_reset() as legacy_jtag_add_reset() with
the target to remove it when all drivers would be ported to the
new reset API. Create a new jtag_add_reset() that calls the
legacy function for drivers still on the old reset API.

Use the new API also on JTAG transport for the drivers that can
support both SWD and JTAG.

For the moment, do not modify the implementation of JTAG-only
drivers, which will continue using the usual method. This should
be cleaned-up in future commits.

Change-Id: I32331c88313f6059b25e12c6bb0156aebc1c074f
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/4895
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
This commit is contained in:
Antonio Borneo 2019-08-31 11:08:16 +02:00 committed by Tomas Vanek
parent db23c13d42
commit 8850eb8f2c
14 changed files with 233 additions and 144 deletions

View File

@ -613,53 +613,42 @@ void jtag_add_clocks(int num_cycles)
}
}
void swd_add_reset(int req_srst)
static int adapter_system_reset(int req_srst)
{
int retval;
if (req_srst) {
if (!(jtag_reset_config & RESET_HAS_SRST)) {
LOG_ERROR("BUG: can't assert SRST");
jtag_set_error(ERROR_FAIL);
return;
return ERROR_FAIL;
}
req_srst = 1;
}
/* Maybe change SRST signal state */
if (jtag_srst != req_srst) {
int retval;
retval = interface_jtag_add_reset(0, req_srst);
if (retval != ERROR_OK)
jtag_set_error(retval);
else
retval = jtag_execute_queue();
retval = jtag->reset(0, req_srst);
if (retval != ERROR_OK) {
LOG_ERROR("TRST/SRST error");
return;
LOG_ERROR("SRST error");
return ERROR_FAIL;
}
/* SRST resets everything hooked up to that signal */
jtag_srst = req_srst;
if (jtag_srst) {
if (req_srst) {
LOG_DEBUG("SRST line asserted");
if (adapter_nsrst_assert_width)
jtag_add_sleep(adapter_nsrst_assert_width * 1000);
jtag_sleep(adapter_nsrst_assert_width * 1000);
} else {
LOG_DEBUG("SRST line released");
if (adapter_nsrst_delay)
jtag_add_sleep(adapter_nsrst_delay * 1000);
}
retval = jtag_execute_queue();
if (retval != ERROR_OK) {
LOG_ERROR("SRST timings error");
return;
jtag_sleep(adapter_nsrst_delay * 1000);
}
}
return ERROR_OK;
}
void jtag_add_reset(int req_tlr_or_trst, int req_srst)
static void legacy_jtag_add_reset(int req_tlr_or_trst, int req_srst)
{
int trst_with_tlr = 0;
int new_srst = 0;
@ -767,6 +756,118 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
}
}
/* FIXME: name is misleading; we do not plan to "add" reset into jtag queue */
void jtag_add_reset(int req_tlr_or_trst, int req_srst)
{
int retval;
int trst_with_tlr = 0;
int new_srst = 0;
int new_trst = 0;
if (!jtag->reset) {
legacy_jtag_add_reset(req_tlr_or_trst, req_srst);
return;
}
/* Without SRST, we must use target-specific JTAG operations
* on each target; callers should not be requesting SRST when
* that signal doesn't exist.
*
* RESET_SRST_PULLS_TRST is a board or chip level quirk, which
* can kick in even if the JTAG adapter can't drive TRST.
*/
if (req_srst) {
if (!(jtag_reset_config & RESET_HAS_SRST)) {
LOG_ERROR("BUG: can't assert SRST");
jtag_set_error(ERROR_FAIL);
return;
}
if ((jtag_reset_config & RESET_SRST_PULLS_TRST) != 0
&& !req_tlr_or_trst) {
LOG_ERROR("BUG: can't assert only SRST");
jtag_set_error(ERROR_FAIL);
return;
}
new_srst = 1;
}
/* JTAG reset (entry to TAP_RESET state) can always be achieved
* using TCK and TMS; that may go through a TAP_{IR,DR}UPDATE
* state first. TRST accelerates it, and bypasses those states.
*
* RESET_TRST_PULLS_SRST is a board or chip level quirk, which
* can kick in even if the JTAG adapter can't drive SRST.
*/
if (req_tlr_or_trst) {
if (!(jtag_reset_config & RESET_HAS_TRST))
trst_with_tlr = 1;
else if ((jtag_reset_config & RESET_TRST_PULLS_SRST) != 0
&& !req_srst)
trst_with_tlr = 1;
else
new_trst = 1;
}
/* Maybe change TRST and/or SRST signal state */
if (jtag_srst != new_srst || jtag_trst != new_trst) {
/* guarantee jtag queue empty before changing reset status */
jtag_execute_queue();
retval = jtag->reset(new_trst, new_srst);
if (retval != ERROR_OK) {
jtag_set_error(retval);
LOG_ERROR("TRST/SRST error");
return;
}
}
/* SRST resets everything hooked up to that signal */
if (jtag_srst != new_srst) {
jtag_srst = new_srst;
if (jtag_srst) {
LOG_DEBUG("SRST line asserted");
if (adapter_nsrst_assert_width)
jtag_add_sleep(adapter_nsrst_assert_width * 1000);
} else {
LOG_DEBUG("SRST line released");
if (adapter_nsrst_delay)
jtag_add_sleep(adapter_nsrst_delay * 1000);
}
}
/* Maybe enter the JTAG TAP_RESET state ...
* - using only TMS, TCK, and the JTAG state machine
* - or else more directly, using TRST
*
* TAP_RESET should be invisible to non-debug parts of the system.
*/
if (trst_with_tlr) {
LOG_DEBUG("JTAG reset with TLR instead of TRST");
jtag_add_tlr();
} else if (jtag_trst != new_trst) {
jtag_trst = new_trst;
if (jtag_trst) {
LOG_DEBUG("TRST line asserted");
tap_set_state(TAP_RESET);
if (jtag_ntrst_assert_width)
jtag_add_sleep(jtag_ntrst_assert_width * 1000);
} else {
LOG_DEBUG("TRST line released");
if (jtag_ntrst_delay)
jtag_add_sleep(jtag_ntrst_delay * 1000);
/* We just asserted nTRST, so we're now in TAP_RESET.
* Inform possible listeners about this, now that
* JTAG instructions and data can be shifted. This
* sequence must match jtag_add_tlr().
*/
jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
jtag_notify_event(JTAG_TRST_ASSERTED);
}
}
}
void jtag_add_sleep(uint32_t us)
{
/** @todo Here, keep_alive() appears to be a layering violation!!! */
@ -1557,17 +1658,19 @@ int adapter_quit(void)
int swd_init_reset(struct command_context *cmd_ctx)
{
int retval = adapter_init(cmd_ctx);
int retval, retval1;
retval = adapter_init(cmd_ctx);
if (retval != ERROR_OK)
return retval;
LOG_DEBUG("Initializing with hard SRST reset");
if (jtag_reset_config & RESET_HAS_SRST)
swd_add_reset(1);
swd_add_reset(0);
retval = jtag_execute_queue();
return retval;
retval = adapter_system_reset(1);
retval1 = adapter_system_reset(0);
return (retval == ERROR_OK) ? retval1 : retval;
}
int jtag_init_reset(struct command_context *cmd_ctx)
@ -1916,7 +2019,7 @@ int adapter_resets(int trst, int srst)
LOG_ERROR("adapter has no srst signal");
return ERROR_FAIL;
}
swd_add_reset(srst);
adapter_system_reset(srst);
return ERROR_OK;
} else if (transport_is_hla()) {
if (trst == TRST_ASSERT) {
@ -1949,7 +2052,7 @@ void adapter_assert_reset(void)
else
jtag_add_reset(0, 1);
} else if (transport_is_swd())
swd_add_reset(1);
adapter_system_reset(1);
else if (get_current_transport() != NULL)
LOG_ERROR("reset is not supported on %s",
get_current_transport()->name);
@ -1962,7 +2065,7 @@ void adapter_deassert_reset(void)
if (transport_is_jtag())
jtag_add_reset(0, 0);
else if (transport_is_swd())
swd_add_reset(0);
adapter_system_reset(0);
else if (get_current_transport() != NULL)
LOG_ERROR("reset is not supported on %s",
get_current_transport()->name);

View File

@ -51,7 +51,6 @@ static volatile uint32_t *pio_base;
static bb_value_t bcm2835gpio_read(void);
static int bcm2835gpio_write(int tck, int tms, int tdi);
static int bcm2835gpio_reset(int trst, int srst);
static int bcm2835_swdio_read(void);
static void bcm2835_swdio_drive(bool is_output);
@ -62,7 +61,6 @@ static int bcm2835gpio_quit(void);
static struct bitbang_interface bcm2835gpio_bitbang = {
.read = bcm2835gpio_read,
.write = bcm2835gpio_write,
.reset = bcm2835gpio_reset,
.swdio_read = bcm2835_swdio_read,
.swdio_drive = bcm2835_swdio_drive,
.blink = NULL
@ -419,6 +417,7 @@ struct jtag_interface bcm2835gpio_interface = {
.commands = bcm2835gpio_command_handlers,
.init = bcm2835gpio_init,
.quit = bcm2835gpio_quit,
.reset = bcm2835gpio_reset,
};
static bool bcm2835gpio_jtag_mode_possible(void)

View File

@ -34,6 +34,7 @@
static int buspirate_execute_queue(void);
static int buspirate_init(void);
static int buspirate_quit(void);
static int buspirate_reset(int trst, int srst);
static void buspirate_end_state(tap_state_t state);
static void buspirate_state_move(void);
@ -133,7 +134,6 @@ static void buspirate_tap_append_scan(int length, uint8_t *buffer,
struct scan_command *command);
static void buspirate_tap_make_space(int scan, int bits);
static void buspirate_reset(int trst, int srst);
static void buspirate_set_feature(int, char, char);
static void buspirate_set_mode(int, char);
static void buspirate_set_speed(int, char);
@ -213,18 +213,6 @@ static int buspirate_execute_queue(void)
buffer, scan_size, cmd->cmd.scan);
break;
case JTAG_RESET:
LOG_DEBUG_IO("reset trst: %i srst %i",
cmd->cmd.reset->trst, cmd->cmd.reset->srst);
/* flush buffers, so we can reset */
buspirate_tap_execute();
if (cmd->cmd.reset->trst == 1)
tap_set_state(TAP_RESET);
buspirate_reset(cmd->cmd.reset->trst,
cmd->cmd.reset->srst);
break;
case JTAG_SLEEP:
LOG_DEBUG_IO("sleep %i", cmd->cmd.sleep->us);
buspirate_tap_execute();
@ -555,7 +543,8 @@ struct jtag_interface buspirate_interface = {
.transports = buspirate_transports,
.swd = &buspirate_swd,
.init = buspirate_init,
.quit = buspirate_quit
.quit = buspirate_quit,
.reset = buspirate_reset,
};
/*************** jtag execute commands **********************/
@ -860,7 +849,7 @@ static void buspirate_tap_append_scan(int length, uint8_t *buffer,
/*************** wrapper functions *********************/
/* (1) assert or (0) deassert reset lines */
static void buspirate_reset(int trst, int srst)
static int buspirate_reset(int trst, int srst)
{
LOG_DEBUG("trst: %i, srst: %i", trst, srst);
@ -873,6 +862,8 @@ static void buspirate_reset(int trst, int srst)
buspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_DISABLE);
else
buspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_ENABLE);
return ERROR_OK;
}
static void buspirate_set_feature(int fd, char feat, char action)

View File

@ -1126,21 +1126,22 @@ static int cmsis_dap_quit(void)
return ERROR_OK;
}
static void cmsis_dap_execute_reset(struct jtag_command *cmd)
static int cmsis_dap_reset(int trst, int srst)
{
/* Set both TRST and SRST even if they're not enabled as
* there's no way to tristate them */
output_pins = 0;
if (!cmd->cmd.reset->srst)
if (!srst)
output_pins |= SWJ_PIN_SRST;
if (!cmd->cmd.reset->trst)
if (!trst)
output_pins |= SWJ_PIN_TRST;
int retval = cmsis_dap_cmd_DAP_SWJ_Pins(output_pins,
SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL);
if (retval != ERROR_OK)
LOG_ERROR("CMSIS-DAP: Interface reset failed");
return retval;
}
static void cmsis_dap_execute_sleep(struct jtag_command *cmd)
@ -1581,10 +1582,6 @@ static void cmsis_dap_execute_tms(struct jtag_command *cmd)
static void cmsis_dap_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
case JTAG_RESET:
cmsis_dap_flush();
cmsis_dap_execute_reset(cmd);
break;
case JTAG_SLEEP:
cmsis_dap_flush();
cmsis_dap_execute_sleep(cmd);
@ -1802,4 +1799,5 @@ struct jtag_interface cmsis_dap_interface = {
.khz = cmsis_dap_khz,
.init = cmsis_dap_init,
.quit = cmsis_dap_quit,
.reset = cmsis_dap_reset,
};

View File

@ -517,46 +517,41 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
tap_state_name(tap_get_end_state()));
}
static void ftdi_execute_reset(struct jtag_command *cmd)
static int ftdi_reset(int trst, int srst)
{
LOG_DEBUG_IO("reset trst: %i srst %i",
cmd->cmd.reset->trst, cmd->cmd.reset->srst);
struct signal *sig_ntrst = find_signal_by_name("nTRST");
struct signal *sig_nsrst = find_signal_by_name("nSRST");
if (cmd->cmd.reset->trst == 1
|| (cmd->cmd.reset->srst
&& (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
tap_set_state(TAP_RESET);
LOG_DEBUG_IO("reset trst: %i srst %i", trst, srst);
struct signal *trst = find_signal_by_name("nTRST");
if (cmd->cmd.reset->trst == 1) {
if (trst)
ftdi_set_signal(trst, '0');
if (trst == 1) {
if (sig_ntrst)
ftdi_set_signal(sig_ntrst, '0');
else
LOG_ERROR("Can't assert TRST: nTRST signal is not defined");
} else if (trst && jtag_get_reset_config() & RESET_HAS_TRST &&
cmd->cmd.reset->trst == 0) {
} else if (sig_ntrst && jtag_get_reset_config() & RESET_HAS_TRST &&
trst == 0) {
if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN)
ftdi_set_signal(trst, 'z');
ftdi_set_signal(sig_ntrst, 'z');
else
ftdi_set_signal(trst, '1');
ftdi_set_signal(sig_ntrst, '1');
}
struct signal *srst = find_signal_by_name("nSRST");
if (cmd->cmd.reset->srst == 1) {
if (srst)
ftdi_set_signal(srst, '0');
if (srst == 1) {
if (sig_nsrst)
ftdi_set_signal(sig_nsrst, '0');
else
LOG_ERROR("Can't assert SRST: nSRST signal is not defined");
} else if (srst && jtag_get_reset_config() & RESET_HAS_SRST &&
cmd->cmd.reset->srst == 0) {
} else if (sig_nsrst && jtag_get_reset_config() & RESET_HAS_SRST &&
srst == 0) {
if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL)
ftdi_set_signal(srst, '1');
ftdi_set_signal(sig_nsrst, '1');
else
ftdi_set_signal(srst, 'z');
ftdi_set_signal(sig_nsrst, 'z');
}
LOG_DEBUG_IO("trst: %i, srst: %i",
cmd->cmd.reset->trst, cmd->cmd.reset->srst);
LOG_DEBUG_IO("trst: %i, srst: %i", trst, srst);
return ERROR_OK;
}
static void ftdi_execute_sleep(struct jtag_command *cmd)
@ -597,9 +592,6 @@ static void ftdi_execute_stableclocks(struct jtag_command *cmd)
static void ftdi_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
case JTAG_RESET:
ftdi_execute_reset(cmd);
break;
case JTAG_RUNTEST:
ftdi_execute_runtest(cmd);
break;
@ -1248,6 +1240,7 @@ struct jtag_interface ftdi_interface = {
.init = ftdi_initialize,
.quit = ftdi_quit,
.reset = ftdi_reset,
.speed = ftdi_speed,
.speed_div = ftdi_speed_div,
.khz = ftdi_khz,

View File

@ -84,7 +84,6 @@ static inline bool gpio_level(int g)
static bb_value_t imx_gpio_read(void);
static int imx_gpio_write(int tck, int tms, int tdi);
static int imx_gpio_reset(int trst, int srst);
static int imx_gpio_swdio_read(void);
static void imx_gpio_swdio_drive(bool is_output);
@ -95,7 +94,6 @@ static int imx_gpio_quit(void);
static struct bitbang_interface imx_gpio_bitbang = {
.read = imx_gpio_read,
.write = imx_gpio_write,
.reset = imx_gpio_reset,
.swdio_read = imx_gpio_swdio_read,
.swdio_drive = imx_gpio_swdio_drive,
.blink = NULL
@ -441,6 +439,7 @@ struct jtag_interface imx_gpio_interface = {
.commands = imx_gpio_command_handlers,
.init = imx_gpio_init,
.quit = imx_gpio_quit,
.reset = imx_gpio_reset,
};
static bool imx_gpio_jtag_mode_possible(void)

View File

@ -94,6 +94,7 @@ static void jlink_path_move(int num_states, tap_state_t *path);
static void jlink_stableclocks(int num_cycles);
static void jlink_runtest(int num_cycles);
static void jlink_reset(int trst, int srst);
static int jlink_reset_safe(int trst, int srst);
static int jlink_swd_run_queue(void);
static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk);
static int jlink_swd_switch_seq(enum swd_special_seq seq);
@ -251,16 +252,6 @@ static void jlink_execute_scan(struct jtag_command *cmd)
tap_state_name(tap_get_end_state()));
}
static void jlink_execute_reset(struct jtag_command *cmd)
{
LOG_DEBUG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst,
cmd->cmd.reset->srst);
jlink_flush();
jlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
jlink_flush();
}
static void jlink_execute_sleep(struct jtag_command *cmd)
{
LOG_DEBUG_IO("sleep %" PRIi32 "", cmd->cmd.sleep->us);
@ -286,9 +277,6 @@ static int jlink_execute_command(struct jtag_command *cmd)
case JTAG_SCAN:
jlink_execute_scan(cmd);
break;
case JTAG_RESET:
jlink_execute_reset(cmd);
break;
case JTAG_SLEEP:
jlink_execute_sleep(cmd);
break;
@ -956,6 +944,13 @@ static void jlink_reset(int trst, int srst)
jaylink_jtag_set_trst(devh);
}
static int jlink_reset_safe(int trst, int srst)
{
jlink_flush();
jlink_reset(trst, srst);
return jlink_flush();
}
COMMAND_HANDLER(jlink_usb_command)
{
int tmp;
@ -2283,6 +2278,7 @@ struct jtag_interface jlink_interface = {
.khz = &jlink_khz,
.init = &jlink_init,
.quit = &jlink_quit,
.reset = &jlink_reset_safe,
.config_trace = &config_trace,
.poll_trace = &poll_trace,
};

View File

@ -819,11 +819,16 @@ static void kitprog_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
/*************** jtag lowlevel functions ********************/
static void kitprog_execute_reset(struct jtag_command *cmd)
static int kitprog_reset(int trst, int srst)
{
int retval = ERROR_OK;
if (cmd->cmd.reset->srst == 1) {
if (trst == 1) {
LOG_ERROR("KitProg: Interface has no TRST");
return ERROR_FAIL;
}
if (srst == 1) {
retval = kitprog_reset_target();
/* Since the previous command also disables SWCLK output, we need to send an
* SWD bus reset command to re-enable it. For some reason, running
@ -836,6 +841,7 @@ static void kitprog_execute_reset(struct jtag_command *cmd)
if (retval != ERROR_OK)
LOG_ERROR("KitProg: Interface reset failed");
return retval;
}
static void kitprog_execute_sleep(struct jtag_command *cmd)
@ -846,9 +852,6 @@ static void kitprog_execute_sleep(struct jtag_command *cmd)
static void kitprog_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
case JTAG_RESET:
kitprog_execute_reset(cmd);
break;
case JTAG_SLEEP:
kitprog_execute_sleep(cmd);
break;
@ -968,5 +971,6 @@ struct jtag_interface kitprog_interface = {
.swd = &kitprog_swd,
.execute_queue = kitprog_execute_queue,
.init = kitprog_init,
.quit = kitprog_quit
.quit = kitprog_quit,
.reset = kitprog_reset,
};

View File

@ -560,12 +560,12 @@ struct jtag_interface sysfsgpio_interface = {
.commands = sysfsgpio_command_handlers,
.init = sysfsgpio_init,
.quit = sysfsgpio_quit,
.reset = sysfsgpio_reset,
};
static struct bitbang_interface sysfsgpio_bitbang = {
.read = sysfsgpio_read,
.write = sysfsgpio_write,
.reset = sysfsgpio_reset,
.swdio_read = sysfsgpio_swdio_read,
.swdio_drive = sysfsgpio_swdio_drive,
.blink = 0

View File

@ -59,7 +59,7 @@ static void vsllink_runtest(int num_cycles);
static void vsllink_stableclocks(int num_cycles, int tms);
static void vsllink_scan(bool ir_scan, enum scan_type type,
uint8_t *buffer, int scan_size, struct scan_command *command);
static void vsllink_reset(int trst, int srst);
static int vsllink_reset(int trst, int srst);
/* VSLLink tap buffer functions */
static void vsllink_tap_append_step(int tms, int tdi);
@ -164,20 +164,6 @@ static int vsllink_execute_queue(void)
cmd->cmd.scan);
break;
case JTAG_RESET:
LOG_DEBUG_IO("reset trst: %i srst %i",
cmd->cmd.reset->trst,
cmd->cmd.reset->srst);
vsllink_tap_execute();
if (cmd->cmd.reset->trst == 1)
tap_set_state(TAP_RESET);
vsllink_reset(cmd->cmd.reset->trst,
cmd->cmd.reset->srst);
break;
case JTAG_SLEEP:
LOG_DEBUG_IO("sleep %i", cmd->cmd.sleep->us);
vsllink_tap_execute();
@ -478,7 +464,7 @@ static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
vsllink_state_move();
}
static void vsllink_reset(int trst, int srst)
static int vsllink_reset(int trst, int srst)
{
LOG_DEBUG("trst: %i, srst: %i", trst, srst);
@ -494,7 +480,7 @@ static void vsllink_reset(int trst, int srst)
versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);
}
versaloon_interface.adaptors.peripheral_commit();
return versaloon_interface.adaptors.peripheral_commit();
}
COMMAND_HANDLER(vsllink_handle_usb_vid_command)
@ -971,6 +957,7 @@ struct jtag_interface vsllink_interface = {
.init = vsllink_init,
.quit = vsllink_quit,
.reset = vsllink_reset,
.khz = vsllink_khz,
.speed = vsllink_speed,
.speed_div = vsllink_speed_div,

View File

@ -1592,35 +1592,44 @@ static void xds110_flush(void)
xds110.txn_result_count = 0;
}
static void xds110_execute_reset(struct jtag_command *cmd)
static int xds110_reset(int trst, int srst)
{
char trst;
char srst;
uint8_t value;
bool success;
int retval = ERROR_OK;
if (cmd->cmd.reset->trst != -1) {
if (cmd->cmd.reset->trst == 0) {
if (trst != -1) {
if (trst == 0) {
/* Deassert nTRST (active low) */
trst = 1;
value = 1;
} else {
/* Assert nTRST (active low) */
trst = 0;
value = 0;
}
(void)xds_set_trst(trst);
success = xds_set_trst(value);
if (!success)
retval = ERROR_FAIL;
}
if (cmd->cmd.reset->srst != -1) {
if (cmd->cmd.reset->srst == 0) {
if (srst != -1) {
if (srst == 0) {
/* Deassert nSRST (active low) */
srst = 1;
value = 1;
} else {
/* Assert nSRST (active low) */
srst = 0;
value = 0;
}
(void)xds_set_srst(srst);
success = xds_set_srst(value);
if (!success)
retval = ERROR_FAIL;
/* Toggle TCK to trigger HIB on CC13x/CC26x devices */
(void)xds_cycle_tck(60000);
success = xds_cycle_tck(60000);
if (!success)
retval = ERROR_FAIL;
}
return retval;
}
static void xds110_execute_sleep(struct jtag_command *cmd)
@ -1788,10 +1797,6 @@ static void xds110_queue_stableclocks(struct jtag_command *cmd)
static void xds110_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
case JTAG_RESET:
xds110_flush();
xds110_execute_reset(cmd);
break;
case JTAG_SLEEP:
xds110_flush();
xds110_execute_sleep(cmd);
@ -2045,4 +2050,5 @@ struct jtag_interface xds110_interface = {
.khz = xds110_khz,
.init = xds110_init,
.quit = xds110_quit,
.reset = xds110_reset,
};

View File

@ -246,6 +246,20 @@ struct jtag_interface {
*/
int (*quit)(void);
/**
* Control (assert/deassert) the signals SRST and TRST on the interface.
* This function is optional.
* Adapters that don't support resets can either not define this function
* or return an error code.
* Adapters that don't support one of the two reset should ignore the
* request to assert the missing signal and eventually log an error.
*
* @param srst 1 to assert SRST, 0 to deassert SRST.
* @param trst 1 to assert TRST, 0 to deassert TRST.
* @returns ERROR_OK on success, or an error code on failure.
*/
int (*reset)(int srst, int trst);
/**
* Returns JTAG maxium speed for KHz. 0 = RTCK. The function returns
* a failure if it can't support the KHz/RTCK.

View File

@ -277,6 +277,5 @@ struct swd_driver {
};
int swd_init_reset(struct command_context *cmd_ctx);
void swd_add_reset(int req_srst);
#endif /* OPENOCD_JTAG_SWD_H */

View File

@ -112,7 +112,7 @@ static int swd_connect(struct adiv5_dap *dap)
if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
if (jtag_reset_config & RESET_SRST_NO_GATING)
swd_add_reset(1);
adapter_assert_reset();
else
LOG_WARNING("\'srst_nogate\' reset_config option is required");
}