diff --git a/src/platforms/libftdi/platform.c b/src/platforms/libftdi/platform.c index d58c9e4..83683c7 100644 --- a/src/platforms/libftdi/platform.c +++ b/src/platforms/libftdi/platform.c @@ -20,6 +20,7 @@ #include "general.h" #include "gdb_if.h" #include "version.h" +#include "platform.h" #include #include @@ -35,15 +36,21 @@ cable_desc_t *active_cable; cable_desc_t cable_desc[] = { { + /* Direct connection from FTDI to Jtag/Swd.*/ .vendor = 0x0403, .product = 0x6010, .interface = INTERFACE_A, .dbus_data = 0x08, .dbus_ddr = 0x1B, + .bitbang_tms_in_port_cmd = GET_BITS_LOW, + .bitbang_tms_in_pin = MPSSE_TMS, .description = "FLOSS-JTAG", .name = "flossjtag" }, { + /* Buffered connection from FTDI to Jtag/Swd. + * TCK and TMS not independant switchable! + * SWD not possible. */ .vendor = 0x0403, .product = 0x6010, .interface = INTERFACE_A, @@ -60,6 +67,9 @@ cable_desc_t cable_desc[] = { * BCBUS 1 (Output) N_SRST * BCBUS 2 (Input) V_ISO available * + * For bitbanged SWD, set Bit 5 low and select SWD read with + * Bit 6 low. Read Connector TMS as FTDI TDO. + * * TDO is routed to Interface 0 RXD as SWO or with Uart * Connector pin 10 pulled to ground will connect Interface 0 RXD * to UART connector RXD @@ -71,6 +81,8 @@ cable_desc_t cable_desc[] = { .dbus_ddr = 0x6B, .cbus_data = 0x02, .cbus_ddr = 0x02, + .bitbang_tms_in_port_cmd = GET_BITS_LOW, + .bitbang_tms_in_pin = MPSSE_TDO, /* keep bit 5 low*/ .name = "ftdiswd" }, { @@ -82,6 +94,9 @@ cable_desc_t cable_desc[] = { .name = "olimex" }, { + /* Buffered connection from FTDI to Jtag/Swd. + * TCK and TMS not independant switchable! + * => SWD not possible. */ .vendor = 0x0403, .product = 0xbdc8, .interface = INTERFACE_A, @@ -90,6 +105,11 @@ cable_desc_t cable_desc[] = { .name = "turtelizer" }, { + /* https://reference.digilentinc.com/jtag_hs1/jtag_hs1 + * No schmeatics available. + * Buffered from FTDI to Jtag/Swd announced + * Independant switch for TMS not known + * => SWD not possible. */ .vendor = 0x0403, .product = 0xbdc8, .interface = INTERFACE_A, @@ -98,14 +118,18 @@ cable_desc_t cable_desc[] = { .name = "jtaghs1" }, { + /* Direct connection from FTDI to Jtag/Swd assumed.*/ .vendor = 0x0403, .product = 0xbdc8, .interface = INTERFACE_A, .dbus_data = 0xA8, .dbus_ddr = 0xAB, + .bitbang_tms_in_port_cmd = GET_BITS_LOW, + .bitbang_tms_in_pin = MPSSE_TMS, .name = "ftdi" }, { + /* Product name not unique! Assume SWD not possible.*/ .vendor = 0x0403, .product = 0x6014, .interface = INTERFACE_A, @@ -116,22 +140,32 @@ cable_desc_t cable_desc[] = { .name = "digilent" }, { + /* Direct connection from FTDI to Jtag/Swd assumed.*/ .vendor = 0x0403, .product = 0x6014, .interface = INTERFACE_A, .dbus_data = 0x08, .dbus_ddr = 0x0B, + .bitbang_tms_in_port_cmd = GET_BITS_LOW, + .bitbang_tms_in_pin = MPSSE_TMS, .name = "ft232h" }, { + /* Direct connection from FTDI to Jtag/Swd assumed.*/ .vendor = 0x0403, .product = 0x6011, .interface = INTERFACE_A, .dbus_data = 0x08, .dbus_ddr = 0x0B, + .bitbang_tms_in_port_cmd = GET_BITS_LOW, + .bitbang_tms_in_pin = MPSSE_TMS, .name = "ft4232h" }, { + /* http://www.olimex.com/dev/pdf/ARM-USB-OCD.pdf. + * BDUS 4 global enables JTAG Buffer. + * => TCK and TMS not independant switchable! + * => SWD not possible. */ .vendor = 0x15ba, .product = 0x002b, .interface = INTERFACE_A, diff --git a/src/platforms/libftdi/platform.h b/src/platforms/libftdi/platform.h index 562f58f..b3fae42 100644 --- a/src/platforms/libftdi/platform.h +++ b/src/platforms/libftdi/platform.h @@ -56,6 +56,8 @@ typedef struct cable_desc_s { uint8_t dbus_ddr; uint8_t cbus_data; uint8_t cbus_ddr; + uint8_t bitbang_tms_in_port_cmd; + uint8_t bitbang_tms_in_pin; char *description; char * name; }cable_desc_t; diff --git a/src/platforms/libftdi/swdptap.c b/src/platforms/libftdi/swdptap.c index 9df9af8..5d6279c 100644 --- a/src/platforms/libftdi/swdptap.c +++ b/src/platforms/libftdi/swdptap.c @@ -36,11 +36,12 @@ static uint8_t olddir = 0; #define MPSSE_TMS_SHIFT (MPSSE_WRITE_TMS | MPSSE_LSB |\ MPSSE_BITMODE | MPSSE_WRITE_NEG) -#define MPSSE_TMS_IN_PORT GET_BITS_LOW -#define MPSSE_TMS_IN_PIN MPSSE_TMS - int swdptap_init(void) { + if (!active_cable->bitbang_tms_in_pin) { + DEBUG("SWD not possible or missing item in cable description.\n"); + return -1; + } int err = ftdi_usb_purge_buffers(ftdic); if (err != 0) { fprintf(stderr, "ftdi_usb_purge_buffer: %d: %s\n", @@ -104,14 +105,14 @@ bool swdptap_bit_in(void) uint8_t cmd[4]; int index = 0; - cmd[index++] = MPSSE_TMS_IN_PORT; + cmd[index++] = active_cable->bitbang_tms_in_port_cmd; cmd[index++] = MPSSE_TMS_SHIFT; cmd[index++] = 0; cmd[index++] = 0; platform_buffer_write(cmd, index); uint8_t data[1]; platform_buffer_read(data, 1); - return (data[0] &= MPSSE_TMS_IN_PIN); + return (data[0] &= active_cable->bitbang_tms_in_pin); } void swdptap_bit_out(bool val) @@ -131,7 +132,7 @@ bool swdptap_seq_in_parity(uint32_t *res, int ticks) uint8_t cmd[4]; unsigned int parity = 0; - cmd[0] = MPSSE_TMS_IN_PORT; + cmd[0] = active_cable->bitbang_tms_in_port_cmd; cmd[1] = MPSSE_TMS_SHIFT; cmd[2] = 0; cmd[3] = 0; @@ -142,10 +143,10 @@ bool swdptap_seq_in_parity(uint32_t *res, int ticks) uint8_t data[33]; unsigned int ret = 0; platform_buffer_read(data, ticks + 1); - if (data[ticks] & 0x08) + if (data[ticks] & active_cable->bitbang_tms_in_pin) parity ^= 1; while (ticks--) { - if (data[ticks] & MPSSE_TMS_IN_PIN) { + if (data[ticks] & active_cable->bitbang_tms_in_pin) { parity ^= 1; ret |= (1 << ticks); } @@ -159,7 +160,7 @@ uint32_t swdptap_seq_in(int ticks) int index = ticks; uint8_t cmd[4]; - cmd[0] = MPSSE_TMS_IN_PORT; + cmd[0] = active_cable->bitbang_tms_in_port_cmd; cmd[1] = MPSSE_TMS_SHIFT; cmd[2] = 0; cmd[3] = 0; @@ -172,7 +173,7 @@ uint32_t swdptap_seq_in(int ticks) uint32_t ret = 0; platform_buffer_read(data, ticks); while (ticks--) { - if (data[ticks] & MPSSE_TMS_IN_PIN) + if (data[ticks] & active_cable->bitbang_tms_in_pin) ret |= (1 << ticks); } return ret; diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index d62a18e..6dfdfd4 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -49,7 +49,8 @@ int adiv5_swdp_scan(void) target_list_free(); ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); - swdptap_init(); + if (swdptap_init()) + return -1; /* Switch from JTAG to SWD mode */ swdptap_seq_out(0xFFFF, 16);