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:
parent
74b3baad1e
commit
6650831243
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue