aboutsummaryrefslogtreecommitdiff
path: root/src/jtag
diff options
context:
space:
mode:
authorStephen Tridgell <stephen.tridgell@exablaze.com>2015-02-25 19:18:27 +1100
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>2016-08-14 02:08:13 +0100
commit2cc1c6daf2a8eea3c4bbda653cf1741afb270644 (patch)
treeab3622e0bf002cce58a765b0b71048f699f6282f /src/jtag
parente3ccae3ed72b47e353fc97d11318a580dadcb7d9 (diff)
downloadriscv-openocd-2cc1c6daf2a8eea3c4bbda653cf1741afb270644.zip
riscv-openocd-2cc1c6daf2a8eea3c4bbda653cf1741afb270644.tar.gz
riscv-openocd-2cc1c6daf2a8eea3c4bbda653cf1741afb270644.tar.bz2
ftdi: Added a method to read the signal values
Change-Id: Ie32a372bbc57249b4802d900234a0e8e7d1d1830 Signed-off-by: Stephen Tridgell <stephen.tridgell@exablaze.com> Reviewed-on: http://openocd.zylin.com/2556 Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Tested-by: jenkins
Diffstat (limited to 'src/jtag')
-rw-r--r--src/jtag/drivers/ftdi.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c
index 8f47468..00fe37f 100644
--- a/src/jtag/drivers/ftdi.c
+++ b/src/jtag/drivers/ftdi.c
@@ -105,8 +105,10 @@ static struct mpsse_ctx *mpsse_ctx;
struct signal {
const char *name;
uint16_t data_mask;
+ uint16_t input_mask;
uint16_t oe_mask;
bool invert_data;
+ bool invert_input;
bool invert_oe;
struct signal *next;
};
@@ -211,6 +213,32 @@ static int ftdi_set_signal(const struct signal *s, char value)
return ERROR_OK;
}
+static int ftdi_get_signal(const struct signal *s, uint16_t * value_out)
+{
+ uint8_t data_low = 0;
+ uint8_t data_high = 0;
+
+ if (s->input_mask == 0) {
+ LOG_ERROR("interface doesn't provide signal '%s'", s->name);
+ return ERROR_FAIL;
+ }
+
+ if (s->input_mask & 0xff)
+ mpsse_read_data_bits_low_byte(mpsse_ctx, &data_low);
+ if (s->input_mask >> 8)
+ mpsse_read_data_bits_high_byte(mpsse_ctx, &data_high);
+
+ mpsse_flush(mpsse_ctx);
+
+ *value_out = (((uint16_t)data_high) << 8) | data_low;
+
+ if (s->invert_input)
+ *value_out = ~(*value_out);
+
+ *value_out &= s->input_mask;
+
+ return ERROR_OK;
+}
/**
* Function move_to_state
@@ -740,6 +768,8 @@ COMMAND_HANDLER(ftdi_handle_layout_signal_command)
bool invert_data = false;
uint16_t data_mask = 0;
+ bool invert_input = false;
+ uint16_t input_mask = 0;
bool invert_oe = false;
uint16_t oe_mask = 0;
for (unsigned i = 1; i < CMD_ARGC; i += 2) {
@@ -749,6 +779,12 @@ COMMAND_HANDLER(ftdi_handle_layout_signal_command)
} else if (strcmp("-ndata", CMD_ARGV[i]) == 0) {
invert_data = true;
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], data_mask);
+ } else if (strcmp("-input", CMD_ARGV[i]) == 0) {
+ invert_input = false;
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], input_mask);
+ } else if (strcmp("-ninput", CMD_ARGV[i]) == 0) {
+ invert_input = true;
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], input_mask);
} else if (strcmp("-oe", CMD_ARGV[i]) == 0) {
invert_oe = false;
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], oe_mask);
@@ -757,15 +793,19 @@ COMMAND_HANDLER(ftdi_handle_layout_signal_command)
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], oe_mask);
} else if (!strcmp("-alias", CMD_ARGV[i]) ||
!strcmp("-nalias", CMD_ARGV[i])) {
- if (!strcmp("-nalias", CMD_ARGV[i]))
+ if (!strcmp("-nalias", CMD_ARGV[i])) {
invert_data = true;
+ invert_input = true;
+ }
struct signal *sig = find_signal_by_name(CMD_ARGV[i + 1]);
if (!sig) {
LOG_ERROR("signal %s is not defined", CMD_ARGV[i + 1]);
return ERROR_FAIL;
}
data_mask = sig->data_mask;
+ input_mask = sig->input_mask;
oe_mask = sig->oe_mask;
+ invert_input ^= sig->invert_input;
invert_oe = sig->invert_oe;
invert_data ^= sig->invert_data;
} else {
@@ -785,6 +825,8 @@ COMMAND_HANDLER(ftdi_handle_layout_signal_command)
sig->invert_data = invert_data;
sig->data_mask = data_mask;
+ sig->invert_input = invert_input;
+ sig->input_mask = input_mask;
sig->invert_oe = invert_oe;
sig->oe_mask = oe_mask;
@@ -821,6 +863,28 @@ COMMAND_HANDLER(ftdi_handle_set_signal_command)
return mpsse_flush(mpsse_ctx);
}
+COMMAND_HANDLER(ftdi_handle_get_signal_command)
+{
+ if (CMD_ARGC < 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct signal *sig;
+ uint16_t sig_data = 0;
+ sig = find_signal_by_name(CMD_ARGV[0]);
+ if (!sig) {
+ LOG_ERROR("interface configuration doesn't define signal '%s'", CMD_ARGV[0]);
+ return ERROR_FAIL;
+ }
+
+ int ret = ftdi_get_signal(sig, &sig_data);
+ if (ret != ERROR_OK)
+ return ret;
+
+ LOG_USER("Signal %s = %#06x", sig->name, sig_data);
+
+ return ERROR_OK;
+}
+
COMMAND_HANDLER(ftdi_handle_vid_pid_command)
{
if (CMD_ARGC > MAX_USB_IDS * 2) {
@@ -929,6 +993,13 @@ static const struct command_registration ftdi_command_handlers[] = {
.usage = "name (1|0|z)",
},
{
+ .name = "ftdi_get_signal",
+ .handler = &ftdi_handle_get_signal_command,
+ .mode = COMMAND_EXEC,
+ .help = "read the value of a layout-specific signal",
+ .usage = "name",
+ },
+ {
.name = "ftdi_vid_pid",
.handler = &ftdi_handle_vid_pid_command,
.mode = COMMAND_CONFIG,