From: Jean-Christian de R. <jc...@ec...> - 2014-12-10 12:29:14
|
Hi Angus, Le 10. 12. 14 04:47, Angus Gratton a écrit : > OB1;3603;0cOn Wed, Dec 10, 2014 at 02:34:21AM +0100, Jean-Christian de Rivaz wrote: >> Correct, but using bad and unreliable workaround. >> >> I have investigated modifications of my patch to resend the last >> operation when a WAIT response is received. Using an logic analyser that >> decode SWD protocol I have found that the SAMD21 do not reply to the >> resent operations and do not reply to the multiple W_ABORT after that. >> Adding delay up to 100ms after the WAIT response don't change the situation. >> >> I don't understand why resending the last operation after a WAIT >> response don't work like mentioned into the "ARM Debug Interface v5® >> Architecture Specification" document. I am lost here. > > My understanding, that I'm guessing you share, is that you should be > seeing FAULT responses to everything after the WAIT, until a write to > ABORT clears the STICKYORUN flag. Thanks for the hint ! The CORUNDETECT bit is set in target/arm_adi_v5.c and is the cause of my problem. Not setting this bit make my patch working very well. > FWIW I don't much like the workaround for SWD WAIT either (it doesn't > work reliably on nrf51822 under some circumstances), and I've spent a > bit of time trying to find an elegant solution to it (including > discussing it on #openocd IRC a bit, and starting-then-abandoning some > patches). I haven't really made any progress. The only ideas I have > seem to require substantial refactoring of openocd, and I have pretty > quickly run into limits in my own understanding of the wider > architecture (and also limits of available time/resources). > > (There's quite possibly a simpler elegant solution I haven't thought > of, though, I'm pretty new to openocd.) > > Please find below my patches proposal for this issue even if it's limited to only for the bitbang driver. The first patch add the SWD transport to the sysfsgpio interface and do all the work including the WAIT handling. It is based on the Paul Fertser initial work on http://openocd.zylin.com/#/c/2004/ . The second patch is a hack to not set the CORUNDETECT bit and is required to make the first patch functional in case of WAIT response. I hope there is a way to disable the CORUNDETECT from the first patch but I have not yet identified how to do that. This link show a logic analyser picture of what happens in case of a WAIT response when programming a SAMD21 flash using the two patches: http://www.eclis.ch/openocd/swd-wait-2.png The openocd configuration file contain the lines below: interface sysfsgpio transport select swd sysfsgpio_swd_nums 19 18 source [find board/atmel_samd21_xplained_pro.cfg] program main.bin verify reset Many thanks to Paul and Angus for your help. Jean-Christian commit 4e38d9190f302265549334147e3e937ab66787f7 Author: Jean-Christian de Rivaz <jc...@ec...> Date: Wed Nov 19 02:53:59 2014 +0100 Add SWD transport to sysfsgpio interface. Replay the last operation in case of WAIT response. Require to NOT set the CORUNDETECT in dap->dp_ctrl_stat. diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c index 795764a..51e3897 100644 --- a/src/jtag/drivers/bitbang.c +++ b/src/jtag/drivers/bitbang.c @@ -337,3 +337,195 @@ int bitbang_execute_queue(void) return retval; } + + +bool swd_mode; +static int queued_retval; + +static int bitbang_swd_init(void) +{ + LOG_DEBUG("bitbang_swd_init"); + swd_mode = true; + return ERROR_OK; +} + +static void bitbang_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsigned int bit_cnt) +{ + LOG_DEBUG("bitbang_exchange"); + int tdi; + + for (unsigned int i = offset; i < bit_cnt + offset; i++) { + int bytec = i/8; + int bcval = 1 << (i % 8); + tdi = !rnw && (buf[bytec] & bcval); + + bitbang_interface->write(0, 0, tdi); + + if (rnw && buf) { + if (bitbang_interface->swdio_read()) + buf[bytec] |= bcval; + else + buf[bytec] &= ~bcval; + } + + bitbang_interface->write(1, 0, tdi); + } +} + +int bitbang_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq) +{ + LOG_DEBUG("bitbang_swd_switch_seq"); + + switch (seq) { + case LINE_RESET: + LOG_DEBUG("SWD line reset"); + bitbang_exchange(false, (uint8_t *)swd_seq_line_reset, 0, swd_seq_line_reset_len); + break; + case JTAG_TO_SWD: + LOG_DEBUG("JTAG-to-SWD"); + bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len); + break; + case SWD_TO_JTAG: + LOG_DEBUG("SWD-to-JTAG"); + bitbang_exchange(false, (uint8_t *)swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len); + break; + default: + LOG_ERROR("Sequence %d not supported", seq); + return ERROR_FAIL; + } + + return ERROR_OK; +} + +void bitbang_switch_to_swd(void) +{ + LOG_DEBUG("bitbang_switch_to_swd"); + bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len); +} + +static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value) +{ + LOG_DEBUG("bitbang_swd_read_reg"); + assert(cmd & SWD_CMD_RnW); + + if (queued_retval != ERROR_OK) { + LOG_DEBUG("Skip bitbang_swd_read_reg because queued_retval=%d", queued_retval); + return; + } + + for (;;) { + uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)]; + + cmd |= SWD_CMD_START | (1 << 7); + bitbang_exchange(false, &cmd, 0, 8); + + bitbang_interface->swdio_drive(false); + bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 32 + 1 + 1); + bitbang_interface->swdio_drive(true); + + int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3); + uint32_t data = buf_get_u32(trn_ack_data_parity_trn, 1 + 3, 32); + int parity = buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 32, 1); + + LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, + ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK", + cmd & SWD_CMD_APnDP ? "AP" : "DP", + cmd & SWD_CMD_RnW ? "read" : "write", + (cmd & SWD_CMD_A32) >> 1, + data); + + if (ack == SWD_ACK_WAIT) { + LOG_DEBUG("SWD_ACK_WAIT"); + continue; + } + + if (ack != SWD_ACK_OK) { + LOG_DEBUG("No acknowledge detected"); + queued_retval = ack; + return; + } + + if (parity != parity_u32(data)) { + LOG_DEBUG("Wrong parity detected"); + queued_retval = ERROR_FAIL; + return; + } + + if (value) + *value = data; + break; + } + + if (cmd & SWD_CMD_APnDP) + bitbang_exchange(true, NULL, 0, dap->memaccess_tck); +} + +static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value) +{ + LOG_DEBUG("bitbang_swd_write_reg"); + assert(!(cmd & SWD_CMD_RnW)); + + if (queued_retval != ERROR_OK) { + LOG_DEBUG("Skip bitbang_swd_write_reg because queued_retval=%d", queued_retval); + return; + } + + for (;;) { + uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)]; + buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32, value); + buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1 + 32, 1, parity_u32(value)); + + cmd |= SWD_CMD_START | (1 << 7); + bitbang_exchange(false, &cmd, 0, 8); + + bitbang_interface->swdio_drive(false); + bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 1); + bitbang_interface->swdio_drive(true); + + int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3); + LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, + ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK", + cmd & SWD_CMD_APnDP ? "AP" : "DP", + cmd & SWD_CMD_RnW ? "read" : "write", + (cmd & SWD_CMD_A32) >> 1, + buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32)); + + if (ack == SWD_ACK_WAIT) { + LOG_DEBUG("SWD_ACK_WAIT"); + continue; + } + + if (ack != SWD_ACK_OK) { + LOG_DEBUG("No acknowledge detected"); + queued_retval = ack; + return; + } + + bitbang_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1); + break; + } + + if (cmd & SWD_CMD_APnDP) + bitbang_exchange(true, NULL, 0, dap->memaccess_tck); +} + +static int bitbang_swd_run_queue(struct adiv5_dap *dap) +{ + LOG_DEBUG("bitbang_swd_run_queue"); + /* A transaction must be followed by another transaction or at least 8 idle cycles to + * ensure that data is clocked through the AP. */ + bitbang_exchange(true, NULL, 0, 8); + + int retval = queued_retval; + queued_retval = ERROR_OK; + LOG_DEBUG("SWD queue return value: %02x", retval); + return retval; +} + +const struct swd_driver bitbang_swd = { + .init = bitbang_swd_init, + .switch_seq = bitbang_swd_switch_seq, + .read_reg = bitbang_swd_read_reg, + .write_reg = bitbang_swd_write_reg, + .run = bitbang_swd_run_queue, +}; diff --git a/src/jtag/drivers/bitbang.h b/src/jtag/drivers/bitbang.h index 6b7d63a..52e113d 100644 --- a/src/jtag/drivers/bitbang.h +++ b/src/jtag/drivers/bitbang.h @@ -24,6 +24,8 @@ #ifndef BITBANG_H #define BITBANG_H +#include <jtag/swd.h> + struct bitbang_interface { /* low level callbacks (for bitbang) */ @@ -31,10 +33,18 @@ struct bitbang_interface { void (*write)(int tck, int tms, int tdi); void (*reset)(int trst, int srst); void (*blink)(int on); + int (*swdio_read)(void); + void (*swdio_drive)(bool on); }; +const struct swd_driver bitbang_swd; + +extern bool swd_mode; + int bitbang_execute_queue(void); extern struct bitbang_interface *bitbang_interface; +void bitbang_switch_to_swd(void); +int bitbang_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq); #endif /* BITBANG_H */ diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index dfb4dcb..72bacdf 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -139,17 +139,26 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) } snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); - if (is_output) - ret = open(buf, O_WRONLY | O_NONBLOCK | O_SYNC); - else - ret = open(buf, O_RDONLY | O_NONBLOCK | O_SYNC); - - if (ret < 0) + ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); + if (ret < 0) { + LOG_ERROR("Couldn't open value for gpio %d", gpio); + perror("sysfsgpio: "); unexport_sysfs_gpio(gpio); + } return ret; } +/* gpio numbers for each gpio. Negative values are invalid */ +static int tck_gpio = -1; +static int tms_gpio = -1; +static int tdi_gpio = -1; +static int tdo_gpio = -1; +static int trst_gpio = -1; +static int srst_gpio = -1; +static int swclk_gpio = -1; +static int swdio_gpio = -1; + /* * file descriptors for /sys/class/gpio/gpioXX/value * Set up during init. @@ -160,6 +169,72 @@ static int tdi_fd = -1; static int tdo_fd = -1; static int trst_fd = -1; static int srst_fd = -1; +static int swclk_fd = -1; +static int swdio_fd = -1; + +static int last_swclk; +static int last_swdio; +static bool last_stored = false; +static bool swdio_input = false; + +static void sysfsgpio_swdio_drive(bool is_output) +{ + char buf[40]; + int ret; + + snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", swdio_gpio); + ret = open_write_close(buf, is_output ? "high" : "in"); + if (ret < 0) { + LOG_ERROR("Couldn't set direction for gpio %d", swdio_gpio); + perror("sysfsgpio: "); + } + + last_stored = false; + swdio_input = !is_output; +} + +static int sysfsgpio_swdio_read(void) +{ + char buf[1]; + + /* important to seek to signal sysfs of new read */ + lseek(swdio_fd, 0, SEEK_SET); + int ret = read(swdio_fd, &buf, sizeof(buf)); + + if (ret < 0) { + LOG_WARNING("reading swdio failed"); + return 0; + } + + return buf[0] == '1'; +} + +static void sysfsgpio_swdio_write(int swclk, int swdio) +{ + const char one[] = "1"; + const char zero[] = "0"; + + size_t bytes_written; + + if (!swdio_input) { + if (!last_stored || (swdio != last_swdio)) { + bytes_written = write(swdio_fd, swdio ? &one : &zero, 1); + if (bytes_written != 1) + LOG_WARNING("writing swdio failed"); + } + } + + /* write swclk last */ + if (!last_stored || (swclk != last_swclk)) { + bytes_written = write(swclk_fd, swclk ? &one : &zero, 1); + if (bytes_written != 1) + LOG_WARNING("writing swclk failed"); + } + + last_swdio = swdio; + last_swclk = swclk; + last_stored = true; +} /* * Bitbang interface read of TDO @@ -191,6 +266,11 @@ static int sysfsgpio_read(void) */ static void sysfsgpio_write(int tck, int tms, int tdi) { + if (swd_mode) { + sysfsgpio_swdio_write(tck, tdi); + return; + } + const char one[] = "1"; const char zero[] = "0"; @@ -239,6 +319,7 @@ static void sysfsgpio_write(int tck, int tms, int tdi) */ static void sysfsgpio_reset(int trst, int srst) { + LOG_DEBUG("sysfsgpio_reset"); const char one[] = "1"; const char zero[] = "0"; size_t bytes_written; @@ -258,14 +339,6 @@ static void sysfsgpio_reset(int trst, int srst) } } -/* gpio numbers for each gpio. Negative values are invalid */ -static int tck_gpio = -1; -static int tms_gpio = -1; -static int tdi_gpio = -1; -static int tdo_gpio = -1; -static int trst_gpio = -1; -static int srst_gpio = -1; - COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionums) { if (CMD_ARGC == 4) { @@ -338,6 +411,40 @@ COMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_trst) return ERROR_OK; } +COMMAND_HANDLER(sysfsgpio_handle_swd_gpionums) +{ + if (CMD_ARGC == 2) { + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); + COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio); + } else if (CMD_ARGC != 0) { + return ERROR_COMMAND_SYNTAX_ERROR; + } + + command_print(CMD_CTX, + "SysfsGPIO nums: swclk = %d, swdio = %d", + swclk_gpio, swdio_gpio); + + return ERROR_OK; +} + +COMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swclk) +{ + if (CMD_ARGC == 1) + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio); + + command_print(CMD_CTX, "SysfsGPIO num: swclk = %d", swclk_gpio); + return ERROR_OK; +} + +COMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swdio) +{ + if (CMD_ARGC == 1) + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio); + + command_print(CMD_CTX, "SysfsGPIO num: swdio = %d", swdio_gpio); + return ERROR_OK; +} + static const struct command_registration sysfsgpio_command_handlers[] = { { .name = "sysfsgpio_jtag_nums", @@ -382,17 +489,39 @@ static const struct command_registration sysfsgpio_command_handlers[] = { .mode = COMMAND_CONFIG, .help = "gpio number for trst.", }, + { + .name = "sysfsgpio_swd_nums", + .handler = &sysfsgpio_handle_swd_gpionums, + .mode = COMMAND_CONFIG, + .help = "gpio numbers for swclk, swdio. (in that order)", + .usage = "(swclk swdio)* ", + }, + { + .name = "sysfsgpio_swclk_num", + .handler = &sysfsgpio_handle_swd_gpionum_swclk, + .mode = COMMAND_CONFIG, + .help = "gpio number for swclk.", + }, + { + .name = "sysfsgpio_swdio_num", + .handler = &sysfsgpio_handle_swd_gpionum_swdio, + .mode = COMMAND_CONFIG, + .help = "gpio number for swdio.", + }, COMMAND_REGISTRATION_DONE }; static int sysfsgpio_init(void); static int sysfsgpio_quit(void); +static const char * const sysfsgpio_transports[] = { "jtag", "swd", NULL }; + struct jtag_interface sysfsgpio_interface = { .name = "sysfsgpio", .supported = DEBUG_CAP_TMS_SEQ, .execute_queue = bitbang_execute_queue, - .transports = jtag_only, + .transports = sysfsgpio_transports, + .swd = &bitbang_swd, .commands = sysfsgpio_command_handlers, .init = sysfsgpio_init, .quit = sysfsgpio_quit, @@ -402,6 +531,8 @@ 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 }; @@ -426,68 +557,108 @@ static void cleanup_all_fds(void) cleanup_fd(srst_fd, srst_gpio); } +static bool sysfsgpio_jtag_mode_possible(void) +{ + if (!is_gpio_valid(tck_gpio)) return 0; + if (!is_gpio_valid(tms_gpio)) return 0; + if (!is_gpio_valid(tdi_gpio)) return 0; + if (!is_gpio_valid(tdo_gpio)) return 0; + return 1; +} + +static bool sysfsgpio_swd_mode_possible(void) +{ + if (!is_gpio_valid(swclk_gpio)) return 0; + if (!is_gpio_valid(swdio_gpio)) return 0; + return 1; +} + static int sysfsgpio_init(void) { bitbang_interface = &sysfsgpio_bitbang; - LOG_INFO("SysfsGPIO JTAG bitbang driver"); - - if (!(is_gpio_valid(tck_gpio) - && is_gpio_valid(tms_gpio) - && is_gpio_valid(tdi_gpio) - && is_gpio_valid(tdo_gpio))) { - if (!is_gpio_valid(tck_gpio)) - LOG_ERROR("gpio num for tck is invalid"); - if (!is_gpio_valid(tms_gpio)) - LOG_ERROR("gpio num for tms is invalid"); - if (!is_gpio_valid(tdo_gpio)) - LOG_ERROR("gpio num for tdo is invalid"); - if (!is_gpio_valid(tdi_gpio)) - LOG_ERROR("gpio num for tdi is invalid"); - - LOG_ERROR("Require tck, tms, tdi and tdo gpios to all be specified"); - return ERROR_JTAG_INIT_FAILED; - } + LOG_INFO("SysfsGPIO JTAG/SWD bitbang driver"); - if (!is_gpio_valid(trst_gpio) && !is_gpio_valid(srst_gpio)) { - LOG_ERROR("Require at least one of trst or srst gpios to be specified"); + if (sysfsgpio_jtag_mode_possible()) { + if (sysfsgpio_swd_mode_possible()) { + LOG_INFO("JTAG and SWD modes enabled"); + } else { + LOG_INFO("JTAG only mode enabled (specify swclk and swdio gpio to add SWD mode)"); + } + if (!is_gpio_valid(trst_gpio) && !is_gpio_valid(srst_gpio)) { + LOG_ERROR("Require at least one of trst or srst gpios to be specified"); + return ERROR_JTAG_INIT_FAILED; + } + } else if (sysfsgpio_swd_mode_possible()) { + LOG_INFO("SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)"); + } else { + LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode and/or swclk and swdio gpio for SWD mode"); return ERROR_JTAG_INIT_FAILED; } + /* * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST * as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high. + * For SWD, SWCLK and SWDIO are configures as output high. */ - tck_fd = setup_sysfs_gpio(tck_gpio, 1, 0); - if (tck_fd < 0) - goto out_error; + if (tck_gpio >= 0) { + tck_fd = setup_sysfs_gpio(tck_gpio, 1, 0); + if (tck_fd < 0) + goto out_error; + } - tms_fd = setup_sysfs_gpio(tms_gpio, 1, 1); - if (tms_fd < 0) - goto out_error; + if (tms_gpio >= 0) { + tms_fd = setup_sysfs_gpio(tms_gpio, 1, 1); + if (tms_fd < 0) + goto out_error; + } - tdi_fd = setup_sysfs_gpio(tdi_gpio, 1, 0); - if (tdi_fd < 0) - goto out_error; + if (tdi_gpio >= 0) { + tdi_fd = setup_sysfs_gpio(tdi_gpio, 1, 0); + if (tdi_fd < 0) + goto out_error; + } - tdo_fd = setup_sysfs_gpio(tdo_gpio, 0, 0); - if (tdo_fd < 0) - goto out_error; + if (tdo_gpio >= 0) { + tdo_fd = setup_sysfs_gpio(tdo_gpio, 0, 0); + if (tdo_fd < 0) + goto out_error; + } /* assume active low*/ - if (trst_gpio > 0) { + if (trst_gpio >= 0) { trst_fd = setup_sysfs_gpio(trst_gpio, 1, 1); if (trst_fd < 0) goto out_error; } /* assume active low*/ - if (srst_gpio > 0) { + if (srst_gpio >= 0) { srst_fd = setup_sysfs_gpio(srst_gpio, 1, 1); if (srst_fd < 0) goto out_error; } + if (swclk_gpio >= 0) { + swclk_fd = setup_sysfs_gpio(swclk_gpio, 1, 0); + if (swclk_fd < 0) + goto out_error; + } + + if (swdio_gpio >= 0) { + swdio_fd = setup_sysfs_gpio(swdio_gpio, 1, 0); + if (swdio_fd < 0) + goto out_error; + } + + if (sysfsgpio_swd_mode_possible()) { + if (swd_mode) + bitbang_swd_switch_seq(NULL, JTAG_TO_SWD); + else + bitbang_swd_switch_seq(NULL, SWD_TO_JTAG); + } + return ERROR_OK; out_error: commit 0ce823c41cf5a63332f20a4083ba6702ba3718ea Author: Jean-Christian de Rivaz <jc...@ec...> Date: Wed Dec 10 12:26:47 2014 +0100 Unset the CORUNDETECT because it make no sense with bitbang driver. diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index c76cc69..5366fc4 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -703,7 +703,7 @@ int ahbap_debugport_init(struct adiv5_dap *dap) if (retval != ERROR_OK) return retval; /* With debug power on we can activate OVERRUN checking */ - dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT; + dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ; retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat); if (retval != ERROR_OK) return retval; |