libftdi: Automatically switch to JTAG if SWD is not possible.

This commit is contained in:
Uwe Bonnes 2020-08-04 20:30:56 +02:00 committed by UweBonnes
parent ae8cb8ab46
commit aeb97466b9
3 changed files with 25 additions and 12 deletions

View File

@ -296,8 +296,11 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
DEBUG_INFO("Using external resistor SWD\n"); DEBUG_INFO("Using external resistor SWD\n");
active_cable->mpsse_swd_read.set_data_low = MPSSE_DO; active_cable->mpsse_swd_read.set_data_low = MPSSE_DO;
active_cable->mpsse_swd_write.set_data_low = MPSSE_DO; active_cable->mpsse_swd_write.set_data_low = MPSSE_DO;
} } else if (!libftdi_swd_possible(NULL, NULL) &&
!cl_opts->opt_usejtag) {
DEBUG_WARN("SWD with cable not possible, trying JTAG\n");
cl_opts->opt_usejtag = true;
}
if(ftdic) { if(ftdic) {
ftdi_usb_close(ftdic); ftdi_usb_close(ftdic);
ftdi_free(ftdic); ftdi_free(ftdic);
@ -457,7 +460,7 @@ void libftdi_buffer_flush(void)
{ {
if (!bufptr) if (!bufptr)
return; return;
DEBUG_WIRE("Flush\n"); DEBUG_WIRE("Flush %d\n", bufptr);
#if defined(USE_USB_VERSION_BIT) #if defined(USE_USB_VERSION_BIT)
static struct ftdi_transfer_control *tc_write = NULL; static struct ftdi_transfer_control *tc_write = NULL;
if (tc_write) if (tc_write)

View File

@ -113,6 +113,7 @@ int libftdi_buffer_read(uint8_t *data, int size);
const char *libftdi_target_voltage(void); const char *libftdi_target_voltage(void);
void libftdi_jtagtap_tdi_tdo_seq( void libftdi_jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks); uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks);
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd);
#define MPSSE_SK 1 #define MPSSE_SK 1
#define PIN0 1 #define PIN0 1

View File

@ -127,7 +127,7 @@ static uint32_t swdptap_seq_in(int ticks);
static void swdptap_seq_out(uint32_t MS, int ticks); static void swdptap_seq_out(uint32_t MS, int ticks);
static void swdptap_seq_out_parity(uint32_t MS, int ticks); static void swdptap_seq_out_parity(uint32_t MS, int ticks);
int libftdi_swdptap_init(swd_proc_t *swd_proc) bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd)
{ {
bool swd_read = bool swd_read =
active_cable->mpsse_swd_read.set_data_low || active_cable->mpsse_swd_read.set_data_low ||
@ -139,8 +139,10 @@ int libftdi_swdptap_init(swd_proc_t *swd_proc)
active_cable->mpsse_swd_write.clr_data_low || active_cable->mpsse_swd_write.clr_data_low ||
active_cable->mpsse_swd_write.set_data_high || active_cable->mpsse_swd_write.set_data_high ||
active_cable->mpsse_swd_write.clr_data_high; active_cable->mpsse_swd_write.clr_data_high;
do_mpsse = swd_read && swd_write; bool mpsse = swd_read && swd_write;
if (!do_mpsse) { if (do_mpsse)
*do_mpsse = mpsse;
if (!mpsse) {
bool bb_swd_read = bool bb_swd_read =
active_cable->bb_swd_read.set_data_low || active_cable->bb_swd_read.set_data_low ||
active_cable->bb_swd_read.clr_data_low || active_cable->bb_swd_read.clr_data_low ||
@ -155,13 +157,20 @@ int libftdi_swdptap_init(swd_proc_t *swd_proc)
active_cable->bb_swdio_in_port_cmd == GET_BITS_LOW && active_cable->bb_swdio_in_port_cmd == GET_BITS_LOW &&
active_cable->bb_swdio_in_pin == MPSSE_CS; active_cable->bb_swdio_in_pin == MPSSE_CS;
if (!bb_swd_read && !bb_swd_write) { if (!bb_swd_read && !bb_swd_write) {
if (bb_direct_possible) if (!bb_direct_possible)
direct_bb_swd = true; return false;
else {
DEBUG_WARN("SWD not possible or missing item in cable description.\n");
return -1;
}
} }
if (direct_bb_swd)
*direct_bb_swd = true;
}
return true;
}
int libftdi_swdptap_init(swd_proc_t *swd_proc)
{
if (!libftdi_swd_possible(&do_mpsse, &direct_bb_swd)) {
DEBUG_WARN("SWD not possible or missing item in cable description.\n");
return -1;
} }
active_state.data_low |= MPSSE_CS | MPSSE_DI | MPSSE_DO; active_state.data_low |= MPSSE_CS | MPSSE_DI | MPSSE_DO;
active_state.data_low &= MPSSE_SK; active_state.data_low &= MPSSE_SK;