drivers/bitbang: remove unused extern declaration of jtag_interface
[openocd.git] / src / jtag / drivers / bitbang.c
index 65028f210a7279997cb03910e4a45ace9831c1ac..da4fb334819755405b83c39f66d596a8c4821c0f 100644 (file)
@@ -16,9 +16,7 @@
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 /* 2014-12: Addition of the SWD protocol support is based on the initial work
@@ -32,9 +30,6 @@
 #include <jtag/interface.h>
 #include <jtag/commands.h>
 
-/* YUK! - but this is currently a global.... */
-extern struct jtag_interface *jtag_interface;
-
 /**
  * Function bitbang_stableclocks
  * issues a number of clock cycles while staying in a stable state.
@@ -43,7 +38,9 @@ extern struct jtag_interface *jtag_interface;
  * this function checks the current stable state to decide on the value of TMS
  * to use.
  */
-static void bitbang_stableclocks(int num_cycles);
+static int bitbang_stableclocks(int num_cycles);
+
+static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);
 
 struct bitbang_interface *bitbang_interface;
 
@@ -70,15 +67,11 @@ struct bitbang_interface *bitbang_interface;
 /* The bitbang driver leaves the TCK 0 when in idle */
 static void bitbang_end_state(tap_state_t state)
 {
-       if (tap_is_state_stable(state))
-               tap_set_end_state(state);
-       else {
-               LOG_ERROR("BUG: %i is not a valid end state", state);
-               exit(-1);
-       }
+       assert(tap_is_state_stable(state));
+       tap_set_end_state(state);
 }
 
-static void bitbang_state_move(int skip)
+static int bitbang_state_move(int skip)
 {
        int i = 0, tms = 0;
        uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
@@ -86,12 +79,16 @@ static void bitbang_state_move(int skip)
 
        for (i = skip; i < tms_count; i++) {
                tms = (tms_scan >> i) & 1;
-               bitbang_interface->write(0, tms, 0);
-               bitbang_interface->write(1, tms, 0);
+               if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
+                       return ERROR_FAIL;
+               if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
+                       return ERROR_FAIL;
        }
-       bitbang_interface->write(CLOCK_IDLE(), tms, 0);
+       if (bitbang_interface->write(CLOCK_IDLE(), tms, 0) != ERROR_OK)
+               return ERROR_FAIL;
 
        tap_set_state(tap_get_end_state());
+       return ERROR_OK;
 }
 
 /**
@@ -108,15 +105,18 @@ static int bitbang_execute_tms(struct jtag_command *cmd)
        int tms = 0;
        for (unsigned i = 0; i < num_bits; i++) {
                tms = ((bits[i/8] >> (i % 8)) & 1);
-               bitbang_interface->write(0, tms, 0);
-               bitbang_interface->write(1, tms, 0);
+               if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
+                       return ERROR_FAIL;
+               if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
+                       return ERROR_FAIL;
        }
-       bitbang_interface->write(CLOCK_IDLE(), tms, 0);
+       if (bitbang_interface->write(CLOCK_IDLE(), tms, 0) != ERROR_OK)
+               return ERROR_FAIL;
 
        return ERROR_OK;
 }
 
-static void bitbang_path_move(struct pathmove_command *cmd)
+static int bitbang_path_move(struct pathmove_command *cmd)
 {
        int num_states = cmd->num_states;
        int state_count;
@@ -135,20 +135,24 @@ static void bitbang_path_move(struct pathmove_command *cmd)
                        exit(-1);
                }
 
-               bitbang_interface->write(0, tms, 0);
-               bitbang_interface->write(1, tms, 0);
+               if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
+                       return ERROR_FAIL;
+               if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
+                       return ERROR_FAIL;
 
                tap_set_state(cmd->path[state_count]);
                state_count++;
                num_states--;
        }
 
-       bitbang_interface->write(CLOCK_IDLE(), tms, 0);
+       if (bitbang_interface->write(CLOCK_IDLE(), tms, 0) != ERROR_OK)
+               return ERROR_FAIL;
 
        tap_set_end_state(tap_get_state());
+       return ERROR_OK;
 }
 
-static void bitbang_runtest(int num_cycles)
+static int bitbang_runtest(int num_cycles)
 {
        int i;
 
@@ -157,38 +161,50 @@ static void bitbang_runtest(int num_cycles)
        /* only do a state_move when we're not already in IDLE */
        if (tap_get_state() != TAP_IDLE) {
                bitbang_end_state(TAP_IDLE);
-               bitbang_state_move(0);
+               if (bitbang_state_move(0) != ERROR_OK)
+                       return ERROR_FAIL;
        }
 
        /* execute num_cycles */
        for (i = 0; i < num_cycles; i++) {
-               bitbang_interface->write(0, 0, 0);
-               bitbang_interface->write(1, 0, 0);
+               if (bitbang_interface->write(0, 0, 0) != ERROR_OK)
+                       return ERROR_FAIL;
+               if (bitbang_interface->write(1, 0, 0) != ERROR_OK)
+                       return ERROR_FAIL;
        }
-       bitbang_interface->write(CLOCK_IDLE(), 0, 0);
+       if (bitbang_interface->write(CLOCK_IDLE(), 0, 0) != ERROR_OK)
+               return ERROR_FAIL;
 
        /* finish in end_state */
        bitbang_end_state(saved_end_state);
        if (tap_get_state() != tap_get_end_state())
-               bitbang_state_move(0);
+               if (bitbang_state_move(0) != ERROR_OK)
+                       return ERROR_FAIL;
+
+       return ERROR_OK;
 }
 
-static void bitbang_stableclocks(int num_cycles)
+static int bitbang_stableclocks(int num_cycles)
 {
        int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
        int i;
 
        /* send num_cycles clocks onto the cable */
        for (i = 0; i < num_cycles; i++) {
-               bitbang_interface->write(1, tms, 0);
-               bitbang_interface->write(0, tms, 0);
+               if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
+                       return ERROR_FAIL;
+               if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
+                       return ERROR_FAIL;
        }
+
+       return ERROR_OK;
 }
 
-static void bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)
+static int bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
+               unsigned scan_size)
 {
        tap_state_t saved_end_state = tap_get_end_state();
-       int bit_cnt;
+       unsigned bit_cnt;
 
        if (!((!ir_scan &&
                        (tap_get_state() == TAP_DRSHIFT)) ||
@@ -198,12 +214,13 @@ static void bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int
                else
                        bitbang_end_state(TAP_DRSHIFT);
 
-               bitbang_state_move(0);
+               if (bitbang_state_move(0) != ERROR_OK)
+                       return ERROR_FAIL;
                bitbang_end_state(saved_end_state);
        }
 
+       size_t buffered = 0;
        for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) {
-               int val = 0;
                int tms = (bit_cnt == scan_size-1) ? 1 : 0;
                int tdi;
                int bytec = bit_cnt/8;
@@ -217,18 +234,47 @@ static void bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int
                if ((type != SCAN_IN) && (buffer[bytec] & bcval))
                        tdi = 1;
 
-               bitbang_interface->write(0, tms, tdi);
-
-               if (type != SCAN_OUT)
-                       val = bitbang_interface->read();
-
-               bitbang_interface->write(1, tms, tdi);
+               if (bitbang_interface->write(0, tms, tdi) != ERROR_OK)
+                       return ERROR_FAIL;
 
                if (type != SCAN_OUT) {
-                       if (val)
-                               buffer[bytec] |= bcval;
-                       else
-                               buffer[bytec] &= ~bcval;
+                       if (bitbang_interface->buf_size) {
+                               if (bitbang_interface->sample() != ERROR_OK)
+                                       return ERROR_FAIL;
+                               buffered++;
+                       } else {
+                               switch (bitbang_interface->read()) {
+                                       case BB_LOW:
+                                               buffer[bytec] &= ~bcval;
+                                               break;
+                                       case BB_HIGH:
+                                               buffer[bytec] |= bcval;
+                                               break;
+                                       default:
+                                               return ERROR_FAIL;
+                               }
+                       }
+               }
+
+               if (bitbang_interface->write(1, tms, tdi) != ERROR_OK)
+                       return ERROR_FAIL;
+
+               if (type != SCAN_OUT && bitbang_interface->buf_size &&
+                               (buffered == bitbang_interface->buf_size ||
+                                bit_cnt == scan_size - 1)) {
+                       for (unsigned i = bit_cnt + 1 - buffered; i <= bit_cnt; i++) {
+                               switch (bitbang_interface->read_sample()) {
+                                       case BB_LOW:
+                                               buffer[i/8] &= ~(1 << (i % 8));
+                                               break;
+                                       case BB_HIGH:
+                                               buffer[i/8] |= 1 << (i % 8);
+                                               break;
+                                       default:
+                                               return ERROR_FAIL;
+                               }
+                       }
+                       buffered = 0;
                }
        }
 
@@ -237,8 +283,10 @@ static void bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int
                 * the shift state, so we skip the first state
                 * and move directly to the end state.
                 */
-               bitbang_state_move(1);
+               if (bitbang_state_move(1) != ERROR_OK)
+                       return ERROR_FAIL;
        }
+       return ERROR_OK;
 }
 
 int bitbang_execute_queue(void)
@@ -259,8 +307,10 @@ int bitbang_execute_queue(void)
         */
        retval = ERROR_OK;
 
-       if (bitbang_interface->blink)
-               bitbang_interface->blink(1);
+       if (bitbang_interface->blink) {
+               if (bitbang_interface->blink(1) != ERROR_OK)
+                       return ERROR_FAIL;
+       }
 
        while (cmd) {
                switch (cmd->type) {
@@ -273,7 +323,9 @@ int bitbang_execute_queue(void)
                                if ((cmd->cmd.reset->trst == 1) ||
                                                (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))
                                        tap_set_state(TAP_RESET);
-                               bitbang_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+                               if (bitbang_interface->reset(cmd->cmd.reset->trst,
+                                                       cmd->cmd.reset->srst) != ERROR_OK)
+                                       return ERROR_FAIL;
                                break;
                        case JTAG_RUNTEST:
 #ifdef _DEBUG_JTAG_IO_
@@ -282,14 +334,16 @@ int bitbang_execute_queue(void)
                                                tap_state_name(cmd->cmd.runtest->end_state));
 #endif
                                bitbang_end_state(cmd->cmd.runtest->end_state);
-                               bitbang_runtest(cmd->cmd.runtest->num_cycles);
+                               if (bitbang_runtest(cmd->cmd.runtest->num_cycles) != ERROR_OK)
+                                       return ERROR_FAIL;
                                break;
 
                        case JTAG_STABLECLOCKS:
                                /* this is only allowed while in a stable state.  A check for a stable
                                 * state was done in jtag_add_clocks()
                                 */
-                               bitbang_stableclocks(cmd->cmd.stableclocks->num_cycles);
+                               if (bitbang_stableclocks(cmd->cmd.stableclocks->num_cycles) != ERROR_OK)
+                                       return ERROR_FAIL;
                                break;
 
                        case JTAG_TLR_RESET:
@@ -298,7 +352,8 @@ int bitbang_execute_queue(void)
                                                tap_state_name(cmd->cmd.statemove->end_state));
 #endif
                                bitbang_end_state(cmd->cmd.statemove->end_state);
-                               bitbang_state_move(0);
+                               if (bitbang_state_move(0) != ERROR_OK)
+                                       return ERROR_FAIL;
                                break;
                        case JTAG_PATHMOVE:
 #ifdef _DEBUG_JTAG_IO_
@@ -306,18 +361,22 @@ int bitbang_execute_queue(void)
                                                cmd->cmd.pathmove->num_states,
                                                tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
 #endif
-                               bitbang_path_move(cmd->cmd.pathmove);
+                               if (bitbang_path_move(cmd->cmd.pathmove) != ERROR_OK)
+                                       return ERROR_FAIL;
                                break;
                        case JTAG_SCAN:
+                               bitbang_end_state(cmd->cmd.scan->end_state);
+                               scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
 #ifdef _DEBUG_JTAG_IO_
-                               LOG_DEBUG("%s scan end in %s",
+                               LOG_DEBUG("%s scan %d bits; end in %s",
                                                (cmd->cmd.scan->ir_scan) ? "IR" : "DR",
+                                               scan_size,
                                        tap_state_name(cmd->cmd.scan->end_state));
 #endif
-                               bitbang_end_state(cmd->cmd.scan->end_state);
-                               scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
                                type = jtag_scan_type(cmd->cmd.scan);
-                               bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
+                               if (bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer,
+                                                       scan_size) != ERROR_OK)
+                                       return ERROR_FAIL;
                                if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
                                        retval = ERROR_JTAG_QUEUE_FAILED;
                                if (buffer)
@@ -338,8 +397,10 @@ int bitbang_execute_queue(void)
                }
                cmd = cmd->next;
        }
-       if (bitbang_interface->blink)
-               bitbang_interface->blink(0);
+       if (bitbang_interface->blink) {
+               if (bitbang_interface->blink(0) != ERROR_OK)
+                       return ERROR_FAIL;
+       }
 
        return retval;
 }
@@ -378,7 +439,7 @@ static void bitbang_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsig
        }
 }
 
-int bitbang_swd_switch_seq(struct adiv5_dap *dap, enum swd_special_seq seq)
+int bitbang_swd_switch_seq(enum swd_special_seq seq)
 {
        LOG_DEBUG("bitbang_swd_switch_seq");
 
@@ -409,16 +470,13 @@ void bitbang_switch_to_swd(void)
        bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);
 }
 
-static void swd_clear_sticky_errors(struct adiv5_dap *dap)
+static void swd_clear_sticky_errors(void)
 {
-       const struct swd_driver *swd = jtag_interface->swd;
-       assert(swd);
-
-       swd->write_reg(dap, swd_cmd(false,  false, DP_ABORT),
-               STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);
+       bitbang_swd_write_reg(swd_cmd(false,  false, DP_ABORT),
+               STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);
 }
 
-static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *value)
+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);
@@ -459,11 +517,11 @@ static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *v
                        if (value)
                                *value = data;
                        if (cmd & SWD_CMD_APnDP)
-                               bitbang_exchange(true, NULL, 0, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
+                               bitbang_exchange(true, NULL, 0, ap_delay_clk);
                        return;
                 case SWD_ACK_WAIT:
                        LOG_DEBUG("SWD_ACK_WAIT");
-                       swd_clear_sticky_errors(dap);
+                       swd_clear_sticky_errors();
                        break;
                 case SWD_ACK_FAULT:
                        LOG_DEBUG("SWD_ACK_FAULT");
@@ -477,7 +535,7 @@ static void bitbang_swd_read_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t *v
        }
 }
 
-static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t value)
+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));
@@ -511,11 +569,11 @@ static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t v
                switch (ack) {
                 case SWD_ACK_OK:
                        if (cmd & SWD_CMD_APnDP)
-                               bitbang_exchange(true, NULL, 0, dap->ap[dap_ap_get_select(dap)].memaccess_tck);
+                               bitbang_exchange(true, NULL, 0, ap_delay_clk);
                        return;
                 case SWD_ACK_WAIT:
                        LOG_DEBUG("SWD_ACK_WAIT");
-                       swd_clear_sticky_errors(dap);
+                       swd_clear_sticky_errors();
                        break;
                 case SWD_ACK_FAULT:
                        LOG_DEBUG("SWD_ACK_FAULT");
@@ -529,7 +587,7 @@ static void bitbang_swd_write_reg(struct adiv5_dap *dap, uint8_t cmd, uint32_t v
        }
 }
 
-static int bitbang_swd_run_queue(struct adiv5_dap *dap)
+static int bitbang_swd_run_queue(void)
 {
        LOG_DEBUG("bitbang_swd_run_queue");
        /* A transaction must be followed by another transaction or at least 8 idle cycles to

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)