drivers/bitbang: add support to switch to/from dormant state
[fw/openocd] / src / jtag / drivers / bitbang.c
index 4417e1258f03decb1bd6fc431dae2d6cc6e5b62f..d202a059610f057b1a462434fe5b80eb875dc228 100644 (file)
@@ -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);
@@ -469,8 +494,8 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay
 
                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_APNDP ? "AP" : "DP",
+                         cmd & SWD_CMD_RNW ? "read" : "write",
                          (cmd & SWD_CMD_A32) >> 1,
                          data);
 
@@ -483,7 +508,7 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay
                        }
                        if (value)
                                *value = data;
-                       if (cmd & SWD_CMD_APnDP)
+                       if (cmd & SWD_CMD_APNDP)
                                bitbang_swd_exchange(true, NULL, 0, ap_delay_clk);
                        return;
                 case SWD_ACK_WAIT:
@@ -505,7 +530,7 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay
 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);
@@ -517,7 +542,7 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay
                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);
@@ -528,14 +553,14 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay
                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_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));
 
                switch (ack) {
                 case SWD_ACK_OK:
-                       if (cmd & SWD_CMD_APnDP)
+                       if (cmd & SWD_CMD_APNDP)
                                bitbang_swd_exchange(true, NULL, 0, ap_delay_clk);
                        return;
                 case SWD_ACK_WAIT: