aboutsummaryrefslogtreecommitdiff
path: root/src/jtag/drivers/ftdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jtag/drivers/ftdi.c')
-rw-r--r--src/jtag/drivers/ftdi.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c
index d8c7d642..7f113918 100644
--- a/src/jtag/drivers/ftdi.c
+++ b/src/jtag/drivers/ftdi.c
@@ -86,11 +86,13 @@
#include "mpsse.h"
#define JTAG_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
+#define JTAG_MODE_ALT (LSB_FIRST | NEG_EDGE_IN | NEG_EDGE_OUT)
#define SWD_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
static char *ftdi_device_desc;
static char *ftdi_serial;
static uint8_t ftdi_channel;
+static uint8_t ftdi_jtag_mode = JTAG_MODE;
static bool swd_mode;
@@ -244,7 +246,7 @@ static void move_to_state(tap_state_t goal_state)
0,
tms_count,
false,
- JTAG_MODE);
+ ftdi_jtag_mode);
}
static int ftdi_speed(int speed)
@@ -257,6 +259,9 @@ static int ftdi_speed(int speed)
return retval;
}
+ if (!swd_mode && speed >= 10000000 && ftdi_jtag_mode != JTAG_MODE_ALT)
+ LOG_INFO("ftdi: if you experience problems at higher adapter clocks, try "
+ "the command \"ftdi_tdo_sample_edge falling\"");
return ERROR_OK;
}
@@ -304,7 +309,7 @@ static void ftdi_execute_runtest(struct jtag_command *cmd)
while (i > 0) {
/* there are no state transitions in this code, so omit state tracking */
unsigned this_len = i > 7 ? 7 : i;
- 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, ftdi_jtag_mode);
i -= this_len;
}
@@ -344,7 +349,7 @@ static void ftdi_execute_tms(struct jtag_command *cmd)
0,
cmd->cmd.tms->num_bits,
false,
- JTAG_MODE);
+ ftdi_jtag_mode);
}
static void ftdi_execute_pathmove(struct jtag_command *cmd)
@@ -391,7 +396,7 @@ static void ftdi_execute_pathmove(struct jtag_command *cmd)
0,
bit_count,
false,
- JTAG_MODE);
+ ftdi_jtag_mode);
bit_count = 0;
}
}
@@ -446,7 +451,7 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
field->in_value,
0,
field->num_bits - 1,
- JTAG_MODE);
+ ftdi_jtag_mode);
uint8_t last_bit = 0;
if (field->out_value)
bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);
@@ -458,14 +463,14 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
field->num_bits - 1,
1,
last_bit,
- JTAG_MODE);
+ ftdi_jtag_mode);
tap_set_state(tap_state_transition(tap_get_state(), 1));
mpsse_clock_tms_cs_out(mpsse_ctx,
&tms_bits,
1,
1,
last_bit,
- JTAG_MODE);
+ ftdi_jtag_mode);
tap_set_state(tap_state_transition(tap_get_state(), 0));
} else
mpsse_clock_data(mpsse_ctx,
@@ -474,7 +479,7 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
field->in_value,
0,
field->num_bits,
- JTAG_MODE);
+ ftdi_jtag_mode);
}
if (tap_get_state() != tap_get_end_state())
@@ -553,7 +558,7 @@ static void ftdi_execute_stableclocks(struct jtag_command *cmd)
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;
- 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, ftdi_jtag_mode);
num_cycles -= this_len;
}
@@ -832,6 +837,29 @@ COMMAND_HANDLER(ftdi_handle_vid_pid_command)
return ERROR_OK;
}
+COMMAND_HANDLER(ftdi_handle_tdo_sample_edge_command)
+{
+ Jim_Nvp *n;
+ static const Jim_Nvp nvp_ftdi_jtag_modes[] = {
+ { .name = "rising", .value = JTAG_MODE },
+ { .name = "falling", .value = JTAG_MODE_ALT },
+ { .name = NULL, .value = -1 },
+ };
+
+ if (CMD_ARGC > 0) {
+ n = Jim_Nvp_name2value_simple(nvp_ftdi_jtag_modes, CMD_ARGV[0]);
+ if (n->name == NULL)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ ftdi_jtag_mode = n->value;
+
+ }
+
+ n = Jim_Nvp_value2name_simple(nvp_ftdi_jtag_modes, ftdi_jtag_mode);
+ command_print(CMD_CTX, "ftdi samples TDO on %s edge of TCK", n->name);
+
+ return ERROR_OK;
+}
+
static const struct command_registration ftdi_command_handlers[] = {
{
.name = "ftdi_device_desc",
@@ -884,6 +912,15 @@ static const struct command_registration ftdi_command_handlers[] = {
.help = "the vendor ID and product ID of the FTDI device",
.usage = "(vid pid)* ",
},
+ {
+ .name = "ftdi_tdo_sample_edge",
+ .handler = &ftdi_handle_tdo_sample_edge_command,
+ .mode = COMMAND_ANY,
+ .help = "set which TCK clock edge is used for sampling TDO "
+ "- default is rising-edge (Setting to falling-edge may "
+ "allow signalling speed increase)",
+ .usage = "(rising|falling)",
+ },
COMMAND_REGISTRATION_DONE
};