X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fbitbang.c;h=898d6d3df9c5d482d167348d8f6b8a8e45416023;hb=9dd39a33e6dbd9d95b5bcfde4b41c498841a27a1;hp=4417e1258f03decb1bd6fc431dae2d6cc6e5b62f;hpb=964680ecff5b252839f61f9328658339d9090bff;p=fw%2Fopenocd diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c index 4417e1258..898d6d3df 100644 --- a/src/jtag/drivers/bitbang.c +++ b/src/jtag/drivers/bitbang.c @@ -358,11 +358,10 @@ int bitbang_execute_queue(void) return ERROR_FAIL; if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) retval = ERROR_JTAG_QUEUE_FAILED; - if (buffer) - free(buffer); + free(buffer); break; case JTAG_SLEEP: - LOG_DEBUG_IO("sleep %" PRIi32, cmd->cmd.sleep->us); + LOG_DEBUG_IO("sleep %" PRIu32, cmd->cmd.sleep->us); jtag_sleep(cmd->cmd.sleep->us); break; case JTAG_TMS: @@ -394,6 +393,11 @@ static void bitbang_swd_exchange(bool rnw, uint8_t buf[], unsigned int offset, u { LOG_DEBUG("bitbang_swd_exchange"); + if (bitbang_interface->blink) { + /* FIXME: we should manage errors */ + bitbang_interface->blink(1); + } + for (unsigned int i = offset; i < bit_cnt + offset; i++) { int bytec = i/8; int bcval = 1 << (i % 8); @@ -410,6 +414,11 @@ static void bitbang_swd_exchange(bool rnw, uint8_t buf[], unsigned int offset, u bitbang_interface->swd_write(1, swdio); } + + if (bitbang_interface->blink) { + /* FIXME: we should manage errors */ + bitbang_interface->blink(0); + } } static int bitbang_swd_switch_seq(enum swd_special_seq seq) @@ -425,10 +434,26 @@ static int bitbang_swd_switch_seq(enum swd_special_seq seq) LOG_DEBUG("JTAG-to-SWD"); bitbang_swd_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len); break; + case JTAG_TO_DORMANT: + LOG_DEBUG("JTAG-to-DORMANT"); + bitbang_swd_exchange(false, (uint8_t *)swd_seq_jtag_to_dormant, 0, swd_seq_jtag_to_dormant_len); + break; case SWD_TO_JTAG: LOG_DEBUG("SWD-to-JTAG"); bitbang_swd_exchange(false, (uint8_t *)swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len); break; + case SWD_TO_DORMANT: + LOG_DEBUG("SWD-to-DORMANT"); + bitbang_swd_exchange(false, (uint8_t *)swd_seq_swd_to_dormant, 0, swd_seq_swd_to_dormant_len); + break; + case DORMANT_TO_SWD: + LOG_DEBUG("DORMANT-to-SWD"); + bitbang_swd_exchange(false, (uint8_t *)swd_seq_dormant_to_swd, 0, swd_seq_dormant_to_swd_len); + break; + case DORMANT_TO_JTAG: + LOG_DEBUG("DORMANT-to-JTAG"); + bitbang_swd_exchange(false, (uint8_t *)swd_seq_dormant_to_jtag, 0, swd_seq_dormant_to_jtag_len); + break; default: LOG_ERROR("Sequence %d not supported", seq); return ERROR_FAIL; @@ -446,7 +471,7 @@ static void swd_clear_sticky_errors(void) static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk) { LOG_DEBUG("bitbang_swd_read_reg"); - assert(cmd & SWD_CMD_RnW); + assert(cmd & SWD_CMD_RNW); if (queued_retval != ERROR_OK) { LOG_DEBUG("Skip bitbang_swd_read_reg because queued_retval=%d", queued_retval); @@ -456,7 +481,7 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay for (;;) { uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)]; - cmd |= SWD_CMD_START | (1 << 7); + cmd |= SWD_CMD_START | SWD_CMD_PARK; bitbang_swd_exchange(false, &cmd, 0, 8); bitbang_interface->swdio_drive(false); @@ -467,57 +492,52 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay 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, + LOG_DEBUG("%s %s read 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_APNDP ? "AP" : "DP", (cmd & SWD_CMD_A32) >> 1, data); - switch (ack) { - case SWD_ACK_OK: - if (parity != parity_u32(data)) { - LOG_DEBUG("Wrong parity detected"); - queued_retval = ERROR_FAIL; - return; - } - if (value) - *value = data; - if (cmd & SWD_CMD_APnDP) - bitbang_swd_exchange(true, NULL, 0, ap_delay_clk); - return; - case SWD_ACK_WAIT: - LOG_DEBUG("SWD_ACK_WAIT"); + if (ack == SWD_ACK_WAIT) { swd_clear_sticky_errors(); - break; - case SWD_ACK_FAULT: - LOG_DEBUG("SWD_ACK_FAULT"); - queued_retval = ack; + continue; + } else if (ack != SWD_ACK_OK) { + queued_retval = swd_ack_to_error_code(ack); return; - default: - LOG_DEBUG("No valid acknowledge: ack=%d", ack); - queued_retval = ack; + } + + if (parity != parity_u32(data)) { + LOG_ERROR("Wrong parity detected"); + queued_retval = ERROR_FAIL; return; } + if (value) + *value = data; + if (cmd & SWD_CMD_APNDP) + bitbang_swd_exchange(true, NULL, 0, ap_delay_clk); + return; } } static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk) { LOG_DEBUG("bitbang_swd_write_reg"); - assert(!(cmd & SWD_CMD_RnW)); + assert(!(cmd & SWD_CMD_RNW)); if (queued_retval != ERROR_OK) { LOG_DEBUG("Skip bitbang_swd_write_reg because queued_retval=%d", queued_retval); return; } + /* Devices do not reply to DP_TARGETSEL write cmd, ignore received ack */ + bool check_ack = swd_cmd_returns_ack(cmd); + 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); + cmd |= SWD_CMD_START | SWD_CMD_PARK; bitbang_swd_exchange(false, &cmd, 0, 8); bitbang_interface->swdio_drive(false); @@ -526,31 +546,27 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay bitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1); int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3); - LOG_DEBUG("%s %s %s reg %X = %08"PRIx32, + + LOG_DEBUG("%s%s %s write reg %X = %08"PRIx32, + check_ack ? "" : "ack ignored ", 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_APNDP ? "AP" : "DP", (cmd & SWD_CMD_A32) >> 1, buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32)); - switch (ack) { - case SWD_ACK_OK: - if (cmd & SWD_CMD_APnDP) - bitbang_swd_exchange(true, NULL, 0, ap_delay_clk); - return; - case SWD_ACK_WAIT: - LOG_DEBUG("SWD_ACK_WAIT"); - swd_clear_sticky_errors(); - break; - case SWD_ACK_FAULT: - LOG_DEBUG("SWD_ACK_FAULT"); - queued_retval = ack; - return; - default: - LOG_DEBUG("No valid acknowledge: ack=%d", ack); - queued_retval = ack; - return; + if (check_ack) { + if (ack == SWD_ACK_WAIT) { + swd_clear_sticky_errors(); + continue; + } else if (ack != SWD_ACK_OK) { + queued_retval = swd_ack_to_error_code(ack); + return; + } } + + if (cmd & SWD_CMD_APNDP) + bitbang_swd_exchange(true, NULL, 0, ap_delay_clk); + return; } }