Simplify the API by making all MPSSE command functions return void instead
of an error code. If there is an error during an implicit flush in a
command call, further commands are ignored until an explicit flush is
performed. The flush function returns and clears any error code set.
The only command functions that still return an error code are those that
can fail directly based on the type of the FTDI chip, i.e. when trying to
enable RCLK or divide-by-5 on a non-high-speed chip.
Adapt the ftdi adapter driver to the new API.
Change-Id: I12979c723c81f7fd022c25821b029112f02b3f95
Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Reviewed-on: http://openocd.zylin.com/1499
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
static int ftdi_set_signal(const struct signal *s, char value)
{
static int ftdi_set_signal(const struct signal *s, char value)
{
else
output = oe ? output | s->oe_mask : output & ~s->oe_mask;
else
output = oe ? output | s->oe_mask : output & ~s->oe_mask;
- retval = mpsse_set_data_bits_low_byte(mpsse_ctx, output & 0xff, direction & 0xff);
- if (retval == ERROR_OK)
- retval = mpsse_set_data_bits_high_byte(mpsse_ctx, output >> 8, direction >> 8);
- if (retval != ERROR_OK) {
- LOG_ERROR("couldn't initialize FTDI GPIO");
- return ERROR_JTAG_INIT_FAILED;
- }
+ mpsse_set_data_bits_low_byte(mpsse_ctx, output & 0xff, direction & 0xff);
+ mpsse_set_data_bits_high_byte(mpsse_ctx, output >> 8, direction >> 8);
*
* @param goal_state is the destination state for the move.
*/
*
* @param goal_state is the destination state for the move.
*/
-static int move_to_state(tap_state_t goal_state)
+static void move_to_state(tap_state_t goal_state)
{
tap_state_t start_state = tap_get_state();
{
tap_state_t start_state = tap_get_state();
for (int i = 0; i < tms_count; i++)
tap_set_state(tap_state_transition(tap_get_state(), (tms_bits >> i) & 1));
for (int i = 0; i < tms_count; i++)
tap_set_state(tap_state_transition(tap_get_state(), (tms_bits >> i) & 1));
- return mpsse_clock_tms_cs_out(mpsse_ctx,
+ mpsse_clock_tms_cs_out(mpsse_ctx,
(uint8_t *)&tms_bits,
0,
tms_count,
(uint8_t *)&tms_bits,
0,
tms_count,
-static int ftdi_execute_runtest(struct jtag_command *cmd)
+static void ftdi_execute_runtest(struct jtag_command *cmd)
/* TODO: Reuse ftdi_execute_stableclocks */
i = cmd->cmd.runtest->num_cycles;
/* TODO: Reuse ftdi_execute_stableclocks */
i = cmd->cmd.runtest->num_cycles;
- while (i > 0 && retval == ERROR_OK) {
/* there are no state transitions in this code, so omit state tracking */
unsigned this_len = i > 7 ? 7 : i;
/* there are no state transitions in this code, so omit state tracking */
unsigned this_len = i > 7 ? 7 : i;
- retval = mpsse_clock_tms_cs_out(mpsse_ctx, &zero, 0, this_len, false, JTAG_MODE);
+ mpsse_clock_tms_cs_out(mpsse_ctx, &zero, 0, this_len, false, JTAG_MODE);
DEBUG_JTAG_IO("runtest: %i, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(tap_get_end_state()));
DEBUG_JTAG_IO("runtest: %i, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(tap_get_end_state()));
-static int ftdi_execute_statemove(struct jtag_command *cmd)
+static void ftdi_execute_statemove(struct jtag_command *cmd)
- int retval = ERROR_OK;
-
DEBUG_JTAG_IO("statemove end in %s",
tap_state_name(cmd->cmd.statemove->end_state));
DEBUG_JTAG_IO("statemove end in %s",
tap_state_name(cmd->cmd.statemove->end_state));
/* shortest-path move to desired end state */
if (tap_get_state() != tap_get_end_state() || tap_get_end_state() == TAP_RESET)
move_to_state(tap_get_end_state());
/* shortest-path move to desired end state */
if (tap_get_state() != tap_get_end_state() || tap_get_end_state() == TAP_RESET)
move_to_state(tap_get_end_state());
}
/**
* Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG
* (or SWD) state machine. REVISIT: Not the best method, perhaps.
*/
}
/**
* Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG
* (or SWD) state machine. REVISIT: Not the best method, perhaps.
*/
-static int ftdi_execute_tms(struct jtag_command *cmd)
+static void ftdi_execute_tms(struct jtag_command *cmd)
{
DEBUG_JTAG_IO("TMS: %d bits", cmd->cmd.tms->num_bits);
/* TODO: Missing tap state tracking, also missing from ft2232.c! */
{
DEBUG_JTAG_IO("TMS: %d bits", cmd->cmd.tms->num_bits);
/* TODO: Missing tap state tracking, also missing from ft2232.c! */
- return mpsse_clock_tms_cs_out(mpsse_ctx,
+ mpsse_clock_tms_cs_out(mpsse_ctx,
cmd->cmd.tms->bits,
0,
cmd->cmd.tms->num_bits,
cmd->cmd.tms->bits,
0,
cmd->cmd.tms->num_bits,
-static int ftdi_execute_pathmove(struct jtag_command *cmd)
+static void ftdi_execute_pathmove(struct jtag_command *cmd)
- int retval = ERROR_OK;
-
tap_state_t *path = cmd->cmd.pathmove->path;
int num_states = cmd->cmd.pathmove->num_states;
tap_state_t *path = cmd->cmd.pathmove->path;
int num_states = cmd->cmd.pathmove->num_states;
DEBUG_JTAG_IO("-");
/* this loop verifies that the path is legal and logs each state in the path */
DEBUG_JTAG_IO("-");
/* this loop verifies that the path is legal and logs each state in the path */
- while (num_states-- && retval == ERROR_OK) {
/* either TMS=0 or TMS=1 must work ... */
if (tap_state_transition(tap_get_state(), false)
/* either TMS=0 or TMS=1 must work ... */
if (tap_state_transition(tap_get_state(), false)
state_count++;
if (bit_count == 7 || num_states == 0) {
state_count++;
if (bit_count == 7 || num_states == 0) {
- retval = mpsse_clock_tms_cs_out(mpsse_ctx,
+ mpsse_clock_tms_cs_out(mpsse_ctx,
}
}
tap_set_end_state(tap_get_state());
}
}
tap_set_end_state(tap_get_state());
-static int ftdi_execute_scan(struct jtag_command *cmd)
+static void ftdi_execute_scan(struct jtag_command *cmd)
- int retval = ERROR_OK;
-
DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN",
jtag_scan_type(cmd->cmd.scan));
DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN",
jtag_scan_type(cmd->cmd.scan));
if (cmd->cmd.scan->num_fields == 0) {
LOG_DEBUG("empty scan, doing nothing");
if (cmd->cmd.scan->num_fields == 0) {
LOG_DEBUG("empty scan, doing nothing");
}
if (cmd->cmd.scan->ir_scan) {
}
if (cmd->cmd.scan->ir_scan) {
if (field->out_value)
bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);
uint8_t tms_bits = 0x01;
if (field->out_value)
bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);
uint8_t tms_bits = 0x01;
- retval = mpsse_clock_tms_cs(mpsse_ctx,
+ mpsse_clock_tms_cs(mpsse_ctx,
&tms_bits,
0,
field->in_value,
&tms_bits,
0,
field->in_value,
last_bit,
JTAG_MODE);
tap_set_state(tap_state_transition(tap_get_state(), 1));
last_bit,
JTAG_MODE);
tap_set_state(tap_state_transition(tap_get_state(), 1));
- retval = mpsse_clock_tms_cs_out(mpsse_ctx,
+ mpsse_clock_tms_cs_out(mpsse_ctx,
0,
field->num_bits,
JTAG_MODE);
0,
field->num_bits,
JTAG_MODE);
- if (retval != ERROR_OK) {
- LOG_ERROR("failed to add field %d in scan", i);
- return retval;
- }
}
if (tap_get_state() != tap_get_end_state())
}
if (tap_get_state() != tap_get_end_state())
DEBUG_JTAG_IO("%s scan, %i bits, end in %s",
(cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
tap_state_name(tap_get_end_state()));
DEBUG_JTAG_IO("%s scan, %i bits, end in %s",
(cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
tap_state_name(tap_get_end_state()));
-static int ftdi_execute_reset(struct jtag_command *cmd)
+static void ftdi_execute_reset(struct jtag_command *cmd)
{
DEBUG_JTAG_IO("reset trst: %i srst %i",
cmd->cmd.reset->trst, cmd->cmd.reset->srst);
{
DEBUG_JTAG_IO("reset trst: %i srst %i",
cmd->cmd.reset->trst, cmd->cmd.reset->srst);
DEBUG_JTAG_IO("trst: %i, srst: %i",
cmd->cmd.reset->trst, cmd->cmd.reset->srst);
DEBUG_JTAG_IO("trst: %i, srst: %i",
cmd->cmd.reset->trst, cmd->cmd.reset->srst);
-static int ftdi_execute_sleep(struct jtag_command *cmd)
+static void ftdi_execute_sleep(struct jtag_command *cmd)
- int retval = ERROR_OK;
-
DEBUG_JTAG_IO("sleep %" PRIi32, cmd->cmd.sleep->us);
DEBUG_JTAG_IO("sleep %" PRIi32, cmd->cmd.sleep->us);
- retval = mpsse_flush(mpsse_ctx);
+ mpsse_flush(mpsse_ctx);
jtag_sleep(cmd->cmd.sleep->us);
DEBUG_JTAG_IO("sleep %" PRIi32 " usec while in %s",
cmd->cmd.sleep->us,
tap_state_name(tap_get_state()));
jtag_sleep(cmd->cmd.sleep->us);
DEBUG_JTAG_IO("sleep %" PRIi32 " usec while in %s",
cmd->cmd.sleep->us,
tap_state_name(tap_get_state()));
-static int ftdi_execute_stableclocks(struct jtag_command *cmd)
+static void ftdi_execute_stableclocks(struct jtag_command *cmd)
- int retval = ERROR_OK;
-
/* this is only allowed while in a stable state. A check for a stable
* state was done in jtag_add_clocks()
*/
/* this is only allowed while in a stable state. A check for a stable
* state was done in jtag_add_clocks()
*/
/* TODO: Use mpsse_clock_data with in=out=0 for this, if TMS can be set to
* the correct level and remain there during the scan */
/* TODO: Use mpsse_clock_data with in=out=0 for this, if TMS can be set to
* the correct level and remain there during the scan */
- while (num_cycles > 0 && retval == ERROR_OK) {
+ while (num_cycles > 0) {
/* there are no state transitions in this code, so omit state tracking */
unsigned this_len = num_cycles > 7 ? 7 : num_cycles;
/* there are no state transitions in this code, so omit state tracking */
unsigned this_len = num_cycles > 7 ? 7 : num_cycles;
- retval = mpsse_clock_tms_cs_out(mpsse_ctx, &tms, 0, this_len, false, JTAG_MODE);
+ mpsse_clock_tms_cs_out(mpsse_ctx, &tms, 0, this_len, false, JTAG_MODE);
num_cycles -= this_len;
}
DEBUG_JTAG_IO("clocks %i while in %s",
cmd->cmd.stableclocks->num_cycles,
tap_state_name(tap_get_state()));
num_cycles -= this_len;
}
DEBUG_JTAG_IO("clocks %i while in %s",
cmd->cmd.stableclocks->num_cycles,
tap_state_name(tap_get_state()));
-static int ftdi_execute_command(struct jtag_command *cmd)
+static void ftdi_execute_command(struct jtag_command *cmd)
switch (cmd->type) {
case JTAG_RESET:
switch (cmd->type) {
case JTAG_RESET:
- retval = ftdi_execute_reset(cmd);
+ ftdi_execute_reset(cmd);
break;
case JTAG_RUNTEST:
break;
case JTAG_RUNTEST:
- retval = ftdi_execute_runtest(cmd);
+ ftdi_execute_runtest(cmd);
break;
case JTAG_TLR_RESET:
break;
case JTAG_TLR_RESET:
- retval = ftdi_execute_statemove(cmd);
+ ftdi_execute_statemove(cmd);
break;
case JTAG_PATHMOVE:
break;
case JTAG_PATHMOVE:
- retval = ftdi_execute_pathmove(cmd);
+ ftdi_execute_pathmove(cmd);
- retval = ftdi_execute_scan(cmd);
+ ftdi_execute_scan(cmd);
- retval = ftdi_execute_sleep(cmd);
+ ftdi_execute_sleep(cmd);
break;
case JTAG_STABLECLOCKS:
break;
case JTAG_STABLECLOCKS:
- retval = ftdi_execute_stableclocks(cmd);
+ ftdi_execute_stableclocks(cmd);
- retval = ftdi_execute_tms(cmd);
break;
default:
LOG_ERROR("BUG: unknown JTAG command type encountered: %d", cmd->type);
break;
default:
LOG_ERROR("BUG: unknown JTAG command type encountered: %d", cmd->type);
- retval = ERROR_JTAG_QUEUE_FAILED;
}
static int ftdi_execute_queue(void)
{
}
static int ftdi_execute_queue(void)
{
- int retval = ERROR_OK;
-
/* blink, if the current layout has that feature */
struct signal *led = find_signal_by_name("LED");
if (led)
/* blink, if the current layout has that feature */
struct signal *led = find_signal_by_name("LED");
if (led)
for (struct jtag_command *cmd = jtag_command_queue; cmd; cmd = cmd->next) {
/* fill the write buffer with the desired command */
for (struct jtag_command *cmd = jtag_command_queue; cmd; cmd = cmd->next) {
/* fill the write buffer with the desired command */
- if (ftdi_execute_command(cmd) != ERROR_OK)
- retval = ERROR_JTAG_QUEUE_FAILED;
+ ftdi_execute_command(cmd);
}
if (led)
ftdi_set_signal(led, '0');
}
if (led)
ftdi_set_signal(led, '0');
- retval = mpsse_flush(mpsse_ctx);
+ int retval = mpsse_flush(mpsse_ctx);
if (retval != ERROR_OK)
LOG_ERROR("error while flushing MPSSE queue: %d", retval);
if (retval != ERROR_OK)
LOG_ERROR("error while flushing MPSSE queue: %d", retval);
static int ftdi_initialize(void)
{
static int ftdi_initialize(void)
{
if (tap_get_tms_path_len(TAP_IRPAUSE, TAP_IRPAUSE) == 7)
LOG_DEBUG("ftdi interface using 7 step jtag state transitions");
else
if (tap_get_tms_path_len(TAP_IRPAUSE, TAP_IRPAUSE) == 7)
LOG_DEBUG("ftdi interface using 7 step jtag state transitions");
else
if (!mpsse_ctx)
return ERROR_JTAG_INIT_FAILED;
if (!mpsse_ctx)
return ERROR_JTAG_INIT_FAILED;
- retval = mpsse_set_data_bits_low_byte(mpsse_ctx, output & 0xff, direction & 0xff);
- if (retval == ERROR_OK)
- retval = mpsse_set_data_bits_high_byte(mpsse_ctx, output >> 8, direction >> 8);
- if (retval != ERROR_OK) {
- LOG_ERROR("couldn't initialize FTDI with configured layout");
- return ERROR_JTAG_INIT_FAILED;
- }
+ mpsse_set_data_bits_low_byte(mpsse_ctx, output & 0xff, direction & 0xff);
+ mpsse_set_data_bits_high_byte(mpsse_ctx, output >> 8, direction >> 8);
- retval = mpsse_loopback_config(mpsse_ctx, false);
- if (retval != ERROR_OK) {
- LOG_ERROR("couldn't write to FTDI to disable loopback");
- return ERROR_JTAG_INIT_FAILED;
- }
+ mpsse_loopback_config(mpsse_ctx, false);
return mpsse_flush(mpsse_ctx);
}
return mpsse_flush(mpsse_ctx);
}
uint8_t *read_chunk;
unsigned read_chunk_size;
struct bit_copy_queue read_queue;
uint8_t *read_chunk;
unsigned read_chunk_size;
struct bit_copy_queue read_queue;
};
/* Returns true if the string descriptor indexed by str_index in device matches string */
};
/* Returns true if the string descriptor indexed by str_index in device matches string */
LOG_DEBUG("-");
ctx->write_count = 0;
ctx->read_count = 0;
LOG_DEBUG("-");
ctx->write_count = 0;
ctx->read_count = 0;
+ ctx->retval = ERROR_OK;
bit_copy_discard(&ctx->read_queue);
err = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST,
SIO_RESET_PURGE_RX, ctx->index, NULL, 0, ctx->usb_write_timeout);
bit_copy_discard(&ctx->read_queue);
err = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST,
SIO_RESET_PURGE_RX, ctx->index, NULL, 0, ctx->usb_write_timeout);
-int mpsse_clock_data_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,
+void mpsse_clock_data_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,
unsigned length, uint8_t mode)
{
unsigned length, uint8_t mode)
{
- return mpsse_clock_data(ctx, out, out_offset, 0, 0, length, mode);
+ mpsse_clock_data(ctx, out, out_offset, 0, 0, length, mode);
-int mpsse_clock_data_in(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, unsigned length,
+void mpsse_clock_data_in(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, unsigned length,
- return mpsse_clock_data(ctx, 0, 0, in, in_offset, length, mode);
+ mpsse_clock_data(ctx, 0, 0, in, in_offset, length, mode);
-int mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,
+void mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,
unsigned in_offset, unsigned length, uint8_t mode)
{
/* TODO: Fix MSB first modes */
DEBUG_IO("%s%s %d bits", in ? "in" : "", out ? "out" : "", length);
unsigned in_offset, unsigned length, uint8_t mode)
{
/* TODO: Fix MSB first modes */
DEBUG_IO("%s%s %d bits", in ? "in" : "", out ? "out" : "", length);
+
+ if (ctx->retval != ERROR_OK) {
+ DEBUG_IO("Ignoring command due to previous error");
+ return;
+ }
/* TODO: On H chips, use command 0x8E/0x8F if in and out are both 0 */
if (out || (!out && !in))
/* TODO: On H chips, use command 0x8E/0x8F if in and out are both 0 */
if (out || (!out && !in))
/* Guarantee buffer space enough for a minimum size transfer */
if (buffer_write_space(ctx) + (length < 8) < (out || (!out && !in) ? 4 : 3)
|| (in && buffer_read_space(ctx) < 1))
/* Guarantee buffer space enough for a minimum size transfer */
if (buffer_write_space(ctx) + (length < 8) < (out || (!out && !in) ? 4 : 3)
|| (in && buffer_read_space(ctx) < 1))
- retval = mpsse_flush(ctx);
+ ctx->retval = mpsse_flush(ctx);
if (length < 8) {
/* Transfer remaining bits in bit mode */
if (length < 8) {
/* Transfer remaining bits in bit mode */
-int mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,
+void mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,
unsigned length, bool tdi, uint8_t mode)
{
unsigned length, bool tdi, uint8_t mode)
{
- return mpsse_clock_tms_cs(ctx, out, out_offset, 0, 0, length, tdi, mode);
+ mpsse_clock_tms_cs(ctx, out, out_offset, 0, 0, length, tdi, mode);
-int mpsse_clock_tms_cs(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,
+void mpsse_clock_tms_cs(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,
unsigned in_offset, unsigned length, bool tdi, uint8_t mode)
{
DEBUG_IO("%sout %d bits, tdi=%d", in ? "in" : "", length, tdi);
assert(out);
unsigned in_offset, unsigned length, bool tdi, uint8_t mode)
{
DEBUG_IO("%sout %d bits, tdi=%d", in ? "in" : "", length, tdi);
assert(out);
+
+ if (ctx->retval != ERROR_OK) {
+ DEBUG_IO("Ignoring command due to previous error");
+ return;
+ }
while (length > 0) {
/* Guarantee buffer space enough for a minimum size transfer */
if (buffer_write_space(ctx) < 3 || (in && buffer_read_space(ctx) < 1))
while (length > 0) {
/* Guarantee buffer space enough for a minimum size transfer */
if (buffer_write_space(ctx) < 3 || (in && buffer_read_space(ctx) < 1))
- retval = mpsse_flush(ctx);
+ ctx->retval = mpsse_flush(ctx);
/* Byte transfer */
unsigned this_bits = length;
/* Byte transfer */
unsigned this_bits = length;
-int mpsse_set_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir)
+void mpsse_set_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir)
+
+ if (ctx->retval != ERROR_OK) {
+ DEBUG_IO("Ignoring command due to previous error");
+ return;
+ }
if (buffer_write_space(ctx) < 3)
if (buffer_write_space(ctx) < 3)
- retval = mpsse_flush(ctx);
+ ctx->retval = mpsse_flush(ctx);
buffer_write_byte(ctx, 0x80);
buffer_write_byte(ctx, data);
buffer_write_byte(ctx, dir);
buffer_write_byte(ctx, 0x80);
buffer_write_byte(ctx, data);
buffer_write_byte(ctx, dir);
-int mpsse_set_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir)
+void mpsse_set_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir)
+
+ if (ctx->retval != ERROR_OK) {
+ DEBUG_IO("Ignoring command due to previous error");
+ return;
+ }
if (buffer_write_space(ctx) < 3)
if (buffer_write_space(ctx) < 3)
- retval = mpsse_flush(ctx);
+ ctx->retval = mpsse_flush(ctx);
buffer_write_byte(ctx, 0x82);
buffer_write_byte(ctx, data);
buffer_write_byte(ctx, dir);
buffer_write_byte(ctx, 0x82);
buffer_write_byte(ctx, data);
buffer_write_byte(ctx, dir);
-int mpsse_read_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t *data)
+void mpsse_read_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t *data)
+
+ if (ctx->retval != ERROR_OK) {
+ DEBUG_IO("Ignoring command due to previous error");
+ return;
+ }
if (buffer_write_space(ctx) < 1)
if (buffer_write_space(ctx) < 1)
- retval = mpsse_flush(ctx);
+ ctx->retval = mpsse_flush(ctx);
buffer_write_byte(ctx, 0x81);
buffer_add_read(ctx, data, 0, 8, 0);
buffer_write_byte(ctx, 0x81);
buffer_add_read(ctx, data, 0, 8, 0);
-int mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t *data)
+void mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t *data)
+
+ if (ctx->retval != ERROR_OK) {
+ DEBUG_IO("Ignoring command due to previous error");
+ return;
+ }
if (buffer_write_space(ctx) < 1)
if (buffer_write_space(ctx) < 1)
- retval = mpsse_flush(ctx);
+ ctx->retval = mpsse_flush(ctx);
buffer_write_byte(ctx, 0x83);
buffer_add_read(ctx, data, 0, 8, 0);
buffer_write_byte(ctx, 0x83);
buffer_add_read(ctx, data, 0, 8, 0);
-static int single_byte_boolean_helper(struct mpsse_ctx *ctx, bool var, uint8_t val_if_true,
+static void single_byte_boolean_helper(struct mpsse_ctx *ctx, bool var, uint8_t val_if_true,
+ if (ctx->retval != ERROR_OK) {
+ DEBUG_IO("Ignoring command due to previous error");
+ return;
+ }
if (buffer_write_space(ctx) < 1)
if (buffer_write_space(ctx) < 1)
- retval = mpsse_flush(ctx);
+ ctx->retval = mpsse_flush(ctx);
buffer_write_byte(ctx, var ? val_if_true : val_if_false);
buffer_write_byte(ctx, var ? val_if_true : val_if_false);
-int mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable)
+void mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable)
{
LOG_DEBUG("%s", enable ? "on" : "off");
{
LOG_DEBUG("%s", enable ? "on" : "off");
- return single_byte_boolean_helper(ctx, enable, 0x84, 0x85);
+ single_byte_boolean_helper(ctx, enable, 0x84, 0x85);
-int mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor)
+void mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor)
{
LOG_DEBUG("%d", divisor);
{
LOG_DEBUG("%d", divisor);
+
+ if (ctx->retval != ERROR_OK) {
+ DEBUG_IO("Ignoring command due to previous error");
+ return;
+ }
if (buffer_write_space(ctx) < 3)
if (buffer_write_space(ctx) < 3)
- retval = mpsse_flush(ctx);
+ ctx->retval = mpsse_flush(ctx);
buffer_write_byte(ctx, 0x86);
buffer_write_byte(ctx, divisor & 0xff);
buffer_write_byte(ctx, divisor >> 8);
buffer_write_byte(ctx, 0x86);
buffer_write_byte(ctx, divisor & 0xff);
buffer_write_byte(ctx, divisor >> 8);
}
int mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable)
}
int mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable)
return ERROR_FAIL;
LOG_DEBUG("%s", enable ? "on" : "off");
return ERROR_FAIL;
LOG_DEBUG("%s", enable ? "on" : "off");
+ single_byte_boolean_helper(ctx, enable, 0x8b, 0x8a);
- return single_byte_boolean_helper(ctx, enable, 0x8b, 0x8a);
}
int mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable)
}
int mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable)
return ERROR_FAIL;
LOG_DEBUG("%s", enable ? "on" : "off");
return ERROR_FAIL;
LOG_DEBUG("%s", enable ? "on" : "off");
+ single_byte_boolean_helper(ctx, enable, 0x96, 0x97);
- return single_byte_boolean_helper(ctx, enable, 0x96, 0x97);
}
int mpsse_set_frequency(struct mpsse_ctx *ctx, int frequency)
}
int mpsse_set_frequency(struct mpsse_ctx *ctx, int frequency)
mpsse_rtck_config(ctx, false); /* just try */
mpsse_rtck_config(ctx, false); /* just try */
- if (frequency > 60000000 / 2 / 65536 && mpsse_is_high_speed(ctx)) {
- int retval = mpsse_divide_by_5_config(ctx, false);
- if (retval != ERROR_OK)
- return retval;
+ if (frequency > 60000000 / 2 / 65536 && mpsse_divide_by_5_config(ctx, false) == ERROR_OK) {
base_clock = 60000000;
} else {
mpsse_divide_by_5_config(ctx, true); /* just try */
base_clock = 60000000;
} else {
mpsse_divide_by_5_config(ctx, true); /* just try */
divisor = 65535;
assert(divisor >= 0);
divisor = 65535;
assert(divisor >= 0);
- int retval = mpsse_set_divisor(ctx, divisor);
- if (retval != ERROR_OK)
- return retval;
+ mpsse_set_divisor(ctx, divisor);
frequency = base_clock / 2 / (1 + divisor);
LOG_DEBUG("actually %d Hz", frequency);
frequency = base_clock / 2 / (1 + divisor);
LOG_DEBUG("actually %d Hz", frequency);
int mpsse_flush(struct mpsse_ctx *ctx)
{
int mpsse_flush(struct mpsse_ctx *ctx)
{
+ int retval = ctx->retval;
+
+ if (retval != ERROR_OK) {
+ DEBUG_IO("Ignoring flush due to previous error");
+ assert(ctx->write_count == 0 && ctx->read_count == 0);
+ ctx->retval = ERROR_OK;
+ return retval;
+ }
+
DEBUG_IO("write %d%s, read %d", ctx->write_count, ctx->read_count ? "+1" : "",
ctx->read_count);
assert(ctx->write_count > 0 || ctx->read_count == 0); /* No read data without write data */
DEBUG_IO("write %d%s, read %d", ctx->write_count, ctx->read_count ? "+1" : "",
ctx->read_count);
assert(ctx->write_count > 0 || ctx->read_count == 0); /* No read data without write data */
if (ctx->write_count == 0)
return retval;
if (ctx->write_count == 0)
return retval;
/* Command queuing. These correspond to the MPSSE commands with the same names, but no need to care
* about bit/byte transfer or data length limitation. Read data is guaranteed to be available only
* after the following mpsse_flush(). */
/* Command queuing. These correspond to the MPSSE commands with the same names, but no need to care
* about bit/byte transfer or data length limitation. Read data is guaranteed to be available only
* after the following mpsse_flush(). */
-int mpsse_clock_data_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,
+void mpsse_clock_data_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,
unsigned length, uint8_t mode);
unsigned length, uint8_t mode);
-int mpsse_clock_data_in(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, unsigned length,
+void mpsse_clock_data_in(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, unsigned length,
-int mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,
+void mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,
unsigned in_offset, unsigned length, uint8_t mode);
unsigned in_offset, unsigned length, uint8_t mode);
-int mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,
+void mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,
unsigned length, bool tdi, uint8_t mode);
unsigned length, bool tdi, uint8_t mode);
-int mpsse_clock_tms_cs(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,
+void mpsse_clock_tms_cs(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,
unsigned in_offset, unsigned length, bool tdi, uint8_t mode);
unsigned in_offset, unsigned length, bool tdi, uint8_t mode);
-int mpsse_set_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir);
-int mpsse_set_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir);
-int mpsse_read_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t *data);
-int mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t *data);
-int mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable);
-int mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor);
+void mpsse_set_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir);
+void mpsse_set_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir);
+void mpsse_read_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t *data);
+void mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t *data);
+void mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable);
+void mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor);
int mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable);
int mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable);
int mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable);
int mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable);
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)