drivers/cmsis_dap: use quirk workarounds optionally
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 <vanekt@fbl.cz> Reviewed-on: https://review.openocd.org/c/openocd/+/7966 Tested-by: jenkins
This commit is contained in:
parent
66391d2837
commit
ba16fdc1c6
|
@ -2569,6 +2569,18 @@ In most cases need not to be specified and interfaces are searched by
|
||||||
interface string or for user class interface.
|
interface string or for user class interface.
|
||||||
@end deffn
|
@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}
|
@deffn {Command} {cmsis-dap info}
|
||||||
Display various device information, like hardware version, firmware version, current bus status.
|
Display various device information, like hardware version, firmware version, current bus status.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
|
@ -861,9 +861,10 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
|
||||||
goto skip;
|
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++;
|
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);
|
LOG_ERROR("internal: too much pending writes %u", dap->pending_fifo_block_count);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -984,6 +985,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
block->transfer_count = 0;
|
block->transfer_count = 0;
|
||||||
|
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_get_idx = (dap->pending_fifo_get_idx + 1) % dap->packet_count;
|
||||||
dap->pending_fifo_block_count--;
|
dap->pending_fifo_block_count--;
|
||||||
}
|
}
|
||||||
|
@ -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. */
|
/* Not enough room in the queue. Run the queue. */
|
||||||
cmsis_dap_swd_write_from_queue(cmsis_dap_handle);
|
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);
|
cmsis_dap_swd_read_process(cmsis_dap_handle, CMSIS_DAP_BLOCKING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1222,7 +1225,7 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
|
||||||
if (swd_mode)
|
if (swd_mode)
|
||||||
queued_retval = cmsis_dap_swd_run_queue();
|
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))
|
(output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST))
|
||||||
== (SWJ_PIN_SRST | SWJ_PIN_TRST)) {
|
== (SWJ_PIN_SRST | SWJ_PIN_TRST)) {
|
||||||
/* Following workaround deasserts reset on most adapters.
|
/* Following workaround deasserts reset on most adapters.
|
||||||
|
@ -2220,6 +2223,19 @@ COMMAND_HANDLER(cmsis_dap_handle_backend_command)
|
||||||
return ERROR_OK;
|
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[] = {
|
static const struct command_registration cmsis_dap_subcommand_handlers[] = {
|
||||||
{
|
{
|
||||||
.name = "info",
|
.name = "info",
|
||||||
|
@ -2249,6 +2265,13 @@ static const struct command_registration cmsis_dap_subcommand_handlers[] = {
|
||||||
.help = "set the communication backend to use (USB bulk or HID).",
|
.help = "set the communication backend to use (USB bulk or HID).",
|
||||||
.usage = "(auto | usb_bulk | 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
|
#if BUILD_CMSIS_DAP_USB
|
||||||
{
|
{
|
||||||
.name = "usb",
|
.name = "usb",
|
||||||
|
|
|
@ -52,6 +52,7 @@ struct cmsis_dap {
|
||||||
unsigned int pending_fifo_block_count;
|
unsigned int pending_fifo_block_count;
|
||||||
|
|
||||||
uint16_t caps;
|
uint16_t caps;
|
||||||
|
bool quirk_mode; /* enable expensive workarounds */
|
||||||
|
|
||||||
uint32_t swo_buf_sz;
|
uint32_t swo_buf_sz;
|
||||||
bool trace_enabled;
|
bool trace_enabled;
|
||||||
|
|
Loading…
Reference in New Issue