ftdi: Get turtelizer (JTAG only FT2232D dongle) going

FT2232D seems to dislike "Set TCK/SK Divisor" or
"Set Data Bits Low Byte" as first command on a non-first run
- Add printout when garbage is found
- Add "Disconnect TDI to TDO for Loopback" as first MPSSE command
  (seemed to help!)
This commit is contained in:
Uwe Bonnes 2020-08-04 19:08:35 +02:00 committed by UweBonnes
parent 74b3baad1e
commit 6650831243
2 changed files with 51 additions and 19 deletions

View File

@ -185,7 +185,7 @@ cable_desc_t cable_desc[] = {
.product = 0xbdc8,
.interface = INTERFACE_A,
/* Drive low to activate JTAGOE and deassert TRST/RST.*/
.init.data_low = PIN6,
.init.data_low = 0,
.init.ddr_low = PIN6 | PIN5 | PIN4,
.init.ddr_high = PIN2, /* ONE LED */
.assert_srst.data_low = PIN6,
@ -361,20 +361,36 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
err, ftdi_get_error_string(ftdic));
goto error_2;
}
uint8_t ftdi_init[9];
ftdi_init[0]= TCK_DIVISOR;
uint8_t ftdi_init[16];
/* Test for pending garbage.*/
int garbage = ftdi_read_data(ftdic, ftdi_init, sizeof(ftdi_init));
if (garbage > 0) {
DEBUG_WARN("FTDI init garbage at start:");
for (int i = 0; i < garbage; i++)
DEBUG_WARN(" %02x", ftdi_init[i]);
DEBUG_WARN("\n");
}
int index = 0;
ftdi_init[index++]= LOOPBACK_END; /* FT2232D gets upset otherwise*/
ftdi_init[index++]= TCK_DIVISOR;
/* Use CLK/2 for about 50 % SWDCLK duty cycle on FT2232c.*/
ftdi_init[1]= 1;
ftdi_init[2]= 0;
ftdi_init[3]= SET_BITS_LOW;
ftdi_init[4]= active_state.data_low;
ftdi_init[5]= active_state.ddr_low;
ftdi_init[6]= SET_BITS_HIGH;
ftdi_init[7]= active_state.data_high;
ftdi_init[8]= active_state.ddr_high;
libftdi_buffer_write(ftdi_init, 9);
ftdi_init[index++]= 1;
ftdi_init[index++]= 0;
ftdi_init[index++]= SET_BITS_LOW;
ftdi_init[index++]= active_state.data_low;
ftdi_init[index++]= active_state.ddr_low;
ftdi_init[index++]= SET_BITS_HIGH;
ftdi_init[index++]= active_state.data_high;
ftdi_init[index++]= active_state.ddr_high;
libftdi_buffer_write(ftdi_init, index);
libftdi_buffer_flush();
return 0;
garbage = ftdi_read_data(ftdic, ftdi_init, sizeof(ftdi_init));
if (garbage > 0) {
DEBUG_WARN("FTDI init garbage at end:");
for (int i = 0; i < garbage; i++)
DEBUG_WARN(" %02x", ftdi_init[i]);
DEBUG_WARN("\n");
} return 0;
error_2:
ftdi_usb_close(ftdic);
@ -596,5 +612,5 @@ const char *libftdi_target_voltage(void)
else
return "Absent";
}
return "not supported";
return NULL;
}

View File

@ -60,16 +60,32 @@ int libftdi_jtagtap_init(jtag_proc_t *jtag_proc)
active_state.ddr_low &= ~(MPSSE_DI);
active_state.data_high |= active_cable->jtag.set_data_high;
active_state.data_high &= ~(active_cable->jtag.clr_data_high);
DEBUG_PROBE("%02x %02x %02x %02x\n", active_state.data_low ,
active_state.ddr_low, active_state.data_high,
active_state.ddr_high);uint8_t cmd_write[6] = {
uint8_t gab[16];
int garbage = ftdi_read_data(ftdic, gab, sizeof(gab));
if (garbage > 0) {
DEBUG_WARN("FTDI JTAG init got garbage:");
for (int i = 0; i < garbage; i++)
DEBUG_WARN(" %02x", gab[i]);
DEBUG_WARN("\n");
}
uint8_t cmd_write[16] = {
SET_BITS_LOW, active_state.data_low,
active_state.ddr_low,
SET_BITS_HIGH, active_state.data_high, active_state.ddr_high};
libftdi_buffer_write(cmd_write, 6);
libftdi_buffer_flush();
/* Write out start condition and pull garbage from read buffer.
* FT2232D otherwise misbehaves on runs follwoing the first run.*/
garbage = ftdi_read_data(ftdic, cmd_write, sizeof(cmd_write));
if (garbage > 0) {
DEBUG_WARN("FTDI JTAG end init got garbage:");
for (int i = 0; i < garbage; i++)
DEBUG_WARN(" %02x", cmd_write[i]);
DEBUG_WARN("\n");
}
/* Go to JTAG mode for SWJ-DP */
for (int i = 0; i <= 50; i++)
jtag_proc->jtagtap_next(1, 0); /* Reset SW-DP */
jtag_proc->jtagtap_next(1, 0); /* Reset SW-DP */
jtag_proc->jtagtap_tms_seq(0xE73C, 16); /* SWD to JTAG sequence */
jtag_proc->jtagtap_tms_seq(0x1F, 6);
@ -84,7 +100,7 @@ static void jtagtap_reset(void)
static void jtagtap_tms_seq(uint32_t MS, int ticks)
{
uint8_t tmp[3] = {
MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE| MPSSE_READ_NEG, 0, 0};
MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG, 0, 0};
while(ticks >= 0) {
tmp[1] = ticks<7?ticks-1:6;
tmp[2] = 0x80 | (MS & 0x7F);