Compare commits

...

9 Commits

Author SHA1 Message Date
Greg Savin 926f555170 Removed IDCODE check. 2019-03-29 13:51:21 -07:00
Greg Savin af1d18f46f Fixed issue with IR width being handled incorrectly in BSCAN tunneled
scans.
2019-03-28 16:39:46 -07:00
Greg Savin fc35fd25fe Simplified bscan_shift routine (never need to stay in shift state at conclusion). 2019-03-28 09:52:43 -07:00
Greg Savin 2b73796a5c Adjusted epilogue width. 2019-03-28 09:48:22 -07:00
Greg Savin 84870e8ada Script file adjustments. 2019-01-16 13:36:35 -08:00
Greg Savin 2c83052b73 Adjustments. 2019-01-15 17:32:55 -08:00
Greg Savin 069a04bcec Forgot to reinitialize "fields" in second loop. 2019-01-15 14:04:45 -08:00
Greg Savin 57b251bb46 New startup scripts for tunneling JTAG through BSCAN chain. 2019-01-14 16:44:42 -08:00
Greg Savin 63272806b3 First attempt at BSCAN tunneling mode. 2019-01-14 10:22:43 -08:00
5 changed files with 240 additions and 0 deletions

View File

@ -111,6 +111,7 @@ m4_define([ADAPTER_OPT], [m4_translit(ADAPTER_ARG($1), [_], [-])])
m4_define([USB1_ADAPTERS],
[[[ftdi], [MPSSE mode of FTDI based devices], [FTDI]],
[[ftdi_oscan1], [cJTAG OSCAN1 tunneled thru MPSSE], [FTDI_OSCAN1]],
[[ftdi_bscan], [BSCAN-to-JTAG via MPSSE], [FTDI_BSCAN]],
[[stlink], [ST-Link JTAG Programmer], [HLADAPTER_STLINK]],
[[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]],
[[ulink], [Keil ULINK JTAG Programmer], [ULINK]],

View File

@ -133,6 +133,12 @@ static void oscan1_mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *
static bool oscan1_mode;
#endif
#if BUILD_FTDI_BSCAN == 1
static bool bscan_mode;
static uint8_t bscan_ir_user = 0x23; /* default USER4 */
static uint32_t bscan_ir_user_width = 6; /* default width of USER4 */
#endif
#define MAX_USB_IDS 8
/* vid = pid = 0 marks the end of the list */
static uint16_t ftdi_vid[MAX_USB_IDS + 1] = { 0 };
@ -497,6 +503,161 @@ static void ftdi_execute_pathmove(struct jtag_command *cmd)
tap_set_end_state(tap_get_state());
}
#if BUILD_FTDI_BSCAN == 1
static void bscan_shift_and_traverse_to_end_state(const uint8_t *out, unsigned out_offset, uint8_t *in,
unsigned in_offset, unsigned length)
{
DO_CLOCK_DATA(mpsse_ctx,
out,
out_offset,
in,
in_offset,
length - 1,
ftdi_jtag_mode);
uint8_t last_bit = 0;
if (out)
bit_copy(&last_bit, 0, out, length - 1, 1);
uint8_t tms_bits = 0x01;
DO_CLOCK_TMS_CS(mpsse_ctx,
&tms_bits,
0,
in,
in_offset + length - 1,
1,
last_bit,
ftdi_jtag_mode);
tap_set_state(tap_state_transition(tap_get_state(), 1));
DO_CLOCK_TMS_CS_OUT(mpsse_ctx,
&tms_bits,
1,
1,
0,
ftdi_jtag_mode);
tap_set_state(tap_state_transition(tap_get_state(), 0));
if (tap_get_state() != tap_get_end_state())
move_to_state(tap_get_end_state());
}
static void ftdi_execute_scan_via_bscan(struct jtag_command *cmd)
{
static const uint8_t zero;
DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN",
jtag_scan_type(cmd->cmd.scan));
/* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */
while (cmd->cmd.scan->num_fields > 0
&& cmd->cmd.scan->fields[cmd->cmd.scan->num_fields - 1].num_bits == 0) {
cmd->cmd.scan->num_fields--;
DEBUG_JTAG_IO("discarding trailing empty field");
}
if (cmd->cmd.scan->num_fields == 0) {
DEBUG_JTAG_IO("empty scan, doing nothing");
return;
}
if (tap_get_state() != TAP_IRSHIFT)
move_to_state(TAP_IRSHIFT);
ftdi_end_state(cmd->cmd.scan->end_state);
// Do the 6-bit IR scan of 0x23 (USER4)
bscan_shift_and_traverse_to_end_state(&bscan_ir_user, 0, NULL, 0, bscan_ir_user_width);
if (tap_get_state() != tap_get_end_state())
move_to_state(tap_get_end_state());
if (tap_get_state() != TAP_DRSHIFT)
move_to_state(TAP_DRSHIFT);
unsigned scan_size = 0;
struct scan_field *field;
int i;
if (cmd->cmd.scan->ir_scan && cmd->cmd.scan->num_fields == 1) {
cmd->cmd.scan->fields[0].num_bits = 5; /* need to override. This is a tunneled IR scan, not a scan of the BSCAN TAP's IR,
so the width is actually 5, by definition */
}
for (i = 0, field = cmd->cmd.scan->fields; i < cmd->cmd.scan->num_fields; i++, field++) {
scan_size += field->num_bits;
}
// shift in prologue
uint8_t prologue = (scan_size << 1) | (cmd->cmd.scan->ir_scan ? 0 : 1);
static const uint8_t epilogue = 0x0;
DO_CLOCK_DATA(mpsse_ctx,
&prologue,
0,
NULL,
0,
8,
ftdi_jtag_mode);
struct scan_field *prevfield = NULL;
for (i = 0, field = cmd->cmd.scan->fields; i < cmd->cmd.scan->num_fields; i++, field++) {
DEBUG_JTAG_IO("%s%s field %d/%d %d bits",
field->in_value ? "in" : "",
field->out_value ? "out" : "",
i,
cmd->cmd.scan->num_fields,
field->num_bits);
// TDO output is off by one clock from TDI, so the sequence is slightly more
// involved than a single aligned OUT/IN
// Clock first bit out, place IN bit in highest bit of prev field if there is a prev field
// Clock rest of bits out, place IN bits in bit zero of in
DO_CLOCK_DATA(mpsse_ctx,
field->out_value,
0,
prevfield ? prevfield->in_value : NULL,
prevfield ? prevfield->num_bits-1 : 0,
1,
ftdi_jtag_mode);
DO_CLOCK_DATA(mpsse_ctx,
field->out_value,
1,
field->in_value,
0,
field->num_bits-1,
ftdi_jtag_mode);
prevfield = field;
}
// There is still one bit left to retrieve in TDO, because of the one clock delay
DO_CLOCK_DATA(mpsse_ctx,
&zero,
0,
prevfield->in_value,
prevfield->num_bits-1,
1,
ftdi_jtag_mode);
// shift in epilogue (3 bits of value zero), exiting shift state and traversing to idle state
bscan_shift_and_traverse_to_end_state(&epilogue, 0, NULL, 0, 3);
if (tap_get_state() != tap_get_end_state())
move_to_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()));
}
#endif
static void ftdi_execute_scan(struct jtag_command *cmd)
{
DEBUG_JTAG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN",
@ -584,6 +745,7 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
tap_state_name(tap_get_end_state()));
}
static void ftdi_execute_reset(struct jtag_command *cmd)
{
DEBUG_JTAG_IO("reset trst: %i srst %i",
@ -683,6 +845,12 @@ static void ftdi_execute_command(struct jtag_command *cmd)
ftdi_execute_pathmove(cmd);
break;
case JTAG_SCAN:
#if BUILD_FTDI_BSCAN == 1
if (bscan_mode) {
ftdi_execute_scan_via_bscan(cmd);
break;
}
#endif
ftdi_execute_scan(cmd);
break;
case JTAG_SLEEP:
@ -1283,6 +1451,22 @@ COMMAND_HANDLER(ftdi_handle_oscan1_mode_command)
}
#endif
#if BUILD_FTDI_BSCAN == 1
COMMAND_HANDLER(ftdi_handle_bscan_mode_command)
{
if (CMD_ARGC > 1)
return ERROR_COMMAND_SYNTAX_ERROR;
if (CMD_ARGC == 1)
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], bscan_mode);
command_print(CMD_CTX, "bscan mode: %s.", bscan_mode ? "on" : "off");
return ERROR_OK;
}
#endif
static const struct command_registration ftdi_command_handlers[] = {
{
.name = "ftdi_device_desc",
@ -1368,6 +1552,15 @@ static const struct command_registration ftdi_command_handlers[] = {
.help = "set to 'on' to use OSCAN1 mode for signaling, otherwise 'off' (default is 'off')",
.usage = "(on|off)",
},
#endif
#if BUILD_FTDI_BSCAN == 1
{
.name = "ftdi_bscan_mode",
.handler = &ftdi_handle_bscan_mode_command,
.mode = COMMAND_ANY,
.help = "set to 'on' to use BSCAN tunneling mode, otherwise 'off' (default is 'off')",
.usage = "(on|off)",
},
#endif
COMMAND_REGISTRATION_DONE
};

View File

@ -0,0 +1,10 @@
#
# Be sure you include the speed and interface before this file
# Example:
# -c "adapter_khz 5000" -f "interface/ftdi/arty-onboard-ftdi.cfg" -f "board/sifive-e31arty-onboard-ftdi.cfg"
set _CHIPNAME arty
jtag newtap $_CHIPNAME bs -irlen 6 -expected-id 0x0362d093
echo "Ready for Remote Connections"

View File

@ -0,0 +1,29 @@
#
# Be sure you include the speed and interface before this file
# Example:
# -c "adapter_khz 5000" -f "interface/ftdi/arty-onboard-ftdi.cfg" -f "board/sifive-e31arty-onboard-ftdi.cfg"
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 6; # -expected-id 0x0362d093
# Arrange for bscan tunneling mode to become active after the JTAG chain is verified (or has been reset but even if the full verification sequence wasn't perfect)
jtag configure $_CHIPNAME.cpu -event setup {
ftdi_bscan_mode on
}
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME
$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
# Uncomment if hardware has flash
# flash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000
init
if {[ info exists pulse_srst]} {
ftdi_set_signal nSRST 0
ftdi_set_signal nSRST z
}
halt
# Uncomment if hardware has flash
# flash protect 0 64 last off
echo "Ready for Remote Connections"

View File

@ -0,0 +1,7 @@
interface ftdi
# ftdi_device_desc "Arty On-board FTDI interface"
ftdi_vid_pid 0x0403 0x6010
ftdi_channel 0
ftdi_layout_init 0x0088 0x008b
reset_config none