Skip to content

Commit

Permalink
drivers/cmsis_dap: use quirk workarounds optionally
Browse files Browse the repository at this point in the history
Introduce 'cmsis-dap quirk' command to enable and
disable quirk mode.

If enabled, disconnect and connect before a switch
sequence and do not use multiple packets pipelining.

Change-Id: I6576f7de9f6c98a25c3cf9eec9a456a23610d00d
Signed-off-by: Tomas Vanek <[email protected]>
Reviewed-on: https://review.openocd.org/c/openocd/+/7966
Tested-by: jenkins
  • Loading branch information
tom-van committed Dec 6, 2023
1 parent 66391d2 commit ba16fdc
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
12 changes: 12 additions & 0 deletions doc/openocd.texi
Original file line number Diff line number Diff line change
Expand Up @@ -2569,6 +2569,18 @@ In most cases need not to be specified and interfaces are searched by
interface string or for user class interface.
@end deffn

@deffn {Command} {cmsis-dap quirk} [@option{enable}|@option{disable}]
Enables or disables the following workarounds of known CMSIS-DAP adapter
quirks:
@itemize @minus
@item disconnect and re-connect before sending a switch sequence
@item packets pipelining is suppressed, only one packet at a time is
submitted to the adapter
@end itemize
The quirk workarounds are disabled by default.
The command without a parameter displays current setting.
@end deffn

@deffn {Command} {cmsis-dap info}
Display various device information, like hardware version, firmware version, current bus status.
@end deffn
Expand Down
33 changes: 28 additions & 5 deletions src/jtag/drivers/cmsis_dap.c
Original file line number Diff line number Diff line change
Expand Up @@ -861,9 +861,10 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
goto skip;
}

dap->pending_fifo_put_idx = (dap->pending_fifo_put_idx + 1) % dap->packet_count;
unsigned int packet_count = dap->quirk_mode ? 1 : dap->packet_count;
dap->pending_fifo_put_idx = (dap->pending_fifo_put_idx + 1) % packet_count;
dap->pending_fifo_block_count++;
if (dap->pending_fifo_block_count > dap->packet_count)
if (dap->pending_fifo_block_count > packet_count)
LOG_ERROR("internal: too much pending writes %u", dap->pending_fifo_block_count);

return;
Expand Down Expand Up @@ -984,7 +985,8 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo

skip:
block->transfer_count = 0;
dap->pending_fifo_get_idx = (dap->pending_fifo_get_idx + 1) % dap->packet_count;
if (!dap->quirk_mode && dap->packet_count > 1)
dap->pending_fifo_get_idx = (dap->pending_fifo_get_idx + 1) % dap->packet_count;
dap->pending_fifo_block_count--;
}

Expand Down Expand Up @@ -1079,7 +1081,8 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
/* Not enough room in the queue. Run the queue. */
cmsis_dap_swd_write_from_queue(cmsis_dap_handle);

if (cmsis_dap_handle->pending_fifo_block_count >= cmsis_dap_handle->packet_count)
unsigned int packet_count = cmsis_dap_handle->quirk_mode ? 1 : cmsis_dap_handle->packet_count;
if (cmsis_dap_handle->pending_fifo_block_count >= packet_count)
cmsis_dap_swd_read_process(cmsis_dap_handle, CMSIS_DAP_BLOCKING);
}

Expand Down Expand Up @@ -1222,7 +1225,7 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
if (swd_mode)
queued_retval = cmsis_dap_swd_run_queue();

if (seq != LINE_RESET &&
if (cmsis_dap_handle->quirk_mode && seq != LINE_RESET &&
(output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST))
== (SWJ_PIN_SRST | SWJ_PIN_TRST)) {
/* Following workaround deasserts reset on most adapters.
Expand Down Expand Up @@ -2220,6 +2223,19 @@ COMMAND_HANDLER(cmsis_dap_handle_backend_command)
return ERROR_OK;
}

COMMAND_HANDLER(cmsis_dap_handle_quirk_command)
{
if (CMD_ARGC > 1)
return ERROR_COMMAND_SYNTAX_ERROR;

if (CMD_ARGC == 1)
COMMAND_PARSE_ENABLE(CMD_ARGV[0], cmsis_dap_handle->quirk_mode);

command_print(CMD, "CMSIS-DAP quirk workarounds %s",
cmsis_dap_handle->quirk_mode ? "enabled" : "disabled");
return ERROR_OK;
}

static const struct command_registration cmsis_dap_subcommand_handlers[] = {
{
.name = "info",
Expand Down Expand Up @@ -2249,6 +2265,13 @@ static const struct command_registration cmsis_dap_subcommand_handlers[] = {
.help = "set the communication backend to use (USB bulk or HID).",
.usage = "(auto | usb_bulk | hid)",
},
{
.name = "quirk",
.handler = &cmsis_dap_handle_quirk_command,
.mode = COMMAND_ANY,
.help = "allow expensive workarounds of known adapter quirks.",
.usage = "[enable | disable]",
},
#if BUILD_CMSIS_DAP_USB
{
.name = "usb",
Expand Down
1 change: 1 addition & 0 deletions src/jtag/drivers/cmsis_dap.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct cmsis_dap {
unsigned int pending_fifo_block_count;

uint16_t caps;
bool quirk_mode; /* enable expensive workarounds */

uint32_t swo_buf_sz;
bool trace_enabled;
Expand Down

0 comments on commit ba16fdc

Please sign in to comment.