From 744deb678d42621c9debdbbbd92481b14418e12c Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 6 Mar 2018 15:05:14 +0100 Subject: [PATCH 01/14] libftdi/platform.c: Only set bit direction with MPSSE SET_BIT_XXXX. --- src/platforms/libftdi/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/libftdi/platform.c b/src/platforms/libftdi/platform.c index 7686e13..2f55a4d 100644 --- a/src/platforms/libftdi/platform.c +++ b/src/platforms/libftdi/platform.c @@ -219,7 +219,7 @@ void platform_init(int argc, char **argv) abort(); } - if((err = ftdi_set_bitmode(ftdic, 0xAB, BITMODE_MPSSE)) != 0) { + if((err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE)) != 0) { fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", err, ftdi_get_error_string(ftdic)); abort(); From f4bc6f9ddd0bc196091bc417e6337a475185fa3d Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 6 Mar 2018 14:15:13 +0100 Subject: [PATCH 02/14] libftdi/platform.c: Issue SEND_IMMEDIATE before reading. --- src/platforms/libftdi/platform.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platforms/libftdi/platform.c b/src/platforms/libftdi/platform.c index 2f55a4d..7c1cdb8 100644 --- a/src/platforms/libftdi/platform.c +++ b/src/platforms/libftdi/platform.c @@ -255,6 +255,7 @@ int platform_buffer_write(const uint8_t *data, int size) int platform_buffer_read(uint8_t *data, int size) { int index = 0; + outbuf[bufptr++] = SEND_IMMEDIATE; platform_buffer_flush(); while((index += ftdi_read_data(ftdic, data + index, size-index)) != size); return size; From 68c718037642755106df8ea9d907c3c44ecfbf36 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Apr 2018 17:02:30 +0200 Subject: [PATCH 03/14] libftdi: Add ftdiswd variant. --- src/platforms/libftdi/platform.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/platforms/libftdi/platform.c b/src/platforms/libftdi/platform.c index 7c1cdb8..d51e559 100644 --- a/src/platforms/libftdi/platform.c +++ b/src/platforms/libftdi/platform.c @@ -60,6 +60,27 @@ static struct cable_desc_s { .description = "FTDIJTAG", .name = "ftdijtag" }, + { +/* UART/SWO on Interface A + * JTAG and control on INTERFACE_B + * Bit 5 high selects SWD-READ (TMS routed to TDO) + * Bit 6 high selects JTAG vs SWD (TMS routed to TDI/TDO) + * BCBUS 1 (Output) N_SRST + * BCBUS 2 (Input) V_ISO available + * + * 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 + */ + .vendor = 0x0403, + .product = 0x6010, + .interface = INTERFACE_B, + .dbus_data = 0x6A, + .dbus_ddr = 0x6B, + .cbus_data = 0x02, + .cbus_ddr = 0x02, + .name = "ftdiswd" + }, { .vendor = 0x15b1, .product = 0x0003, From 6f0a46d9c102f895ef11ef365ea34466c9c2b228 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Apr 2018 22:46:28 +0200 Subject: [PATCH 04/14] libftdi: Export active cable description. --- src/platforms/libftdi/platform.c | 38 ++++++++++++++------------------ src/platforms/libftdi/platform.h | 14 ++++++++++++ 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/platforms/libftdi/platform.c b/src/platforms/libftdi/platform.c index d51e559..43bc68f 100644 --- a/src/platforms/libftdi/platform.c +++ b/src/platforms/libftdi/platform.c @@ -31,17 +31,9 @@ struct ftdi_context *ftdic; static uint8_t outbuf[BUF_SIZE]; static uint16_t bufptr = 0; -static struct cable_desc_s { - int vendor; - int product; - int interface; - uint8_t dbus_data; - uint8_t dbus_ddr; - uint8_t cbus_data; - uint8_t cbus_ddr; - char *description; - char * name; -} cable_desc[] = { +cable_desc_t *active_cable; + +cable_desc_t cable_desc[] = { { .vendor = 0x0403, .product = 0x6010, @@ -182,14 +174,16 @@ void platform_init(int argc, char **argv) exit(-1); } - if (cable_desc[index].dbus_data) - ftdi_init[4]= cable_desc[index].dbus_data; - if (cable_desc[index].dbus_ddr) - ftdi_init[5]= cable_desc[index].dbus_ddr; - if (cable_desc[index].cbus_data) - ftdi_init[7]= cable_desc[index].cbus_data; - if(cable_desc[index].cbus_ddr) - ftdi_init[8]= cable_desc[index].cbus_ddr; + active_cable = &cable_desc[index]; + + if (active_cable->dbus_data) + ftdi_init[4]= active_cable->dbus_data; + if (active_cable->dbus_ddr) + ftdi_init[5]= active_cable->dbus_ddr; + if (active_cable->cbus_data) + ftdi_init[7]= active_cable->cbus_data; + if(active_cable->cbus_ddr) + ftdi_init[8]= active_cable->cbus_ddr; printf("\nBlack Magic Probe (" FIRMWARE_VERSION ")\n"); printf("Copyright (C) 2015 Black Sphere Technologies Ltd.\n"); @@ -206,14 +200,14 @@ void platform_init(int argc, char **argv) ftdi_get_error_string(ftdic)); abort(); } - if((err = ftdi_set_interface(ftdic, cable_desc[index].interface)) != 0) { + if((err = ftdi_set_interface(ftdic, active_cable->interface)) != 0) { fprintf(stderr, "ftdi_set_interface: %d: %s\n", err, ftdi_get_error_string(ftdic)); abort(); } if((err = ftdi_usb_open_desc( - ftdic, cable_desc[index].vendor, cable_desc[index].product, - cable_desc[index].description, serial)) != 0) { + ftdic, active_cable->vendor, active_cable->product, + active_cable->description, serial)) != 0) { fprintf(stderr, "unable to open ftdi device: %d (%s)\n", err, ftdi_get_error_string(ftdic)); abort(); diff --git a/src/platforms/libftdi/platform.h b/src/platforms/libftdi/platform.h index 84fa7f3..7b4f4b9 100644 --- a/src/platforms/libftdi/platform.h +++ b/src/platforms/libftdi/platform.h @@ -48,6 +48,20 @@ void platform_buffer_flush(void); int platform_buffer_write(const uint8_t *data, int size); int platform_buffer_read(uint8_t *data, int size); +typedef struct cable_desc_s { + int vendor; + int product; + int interface; + uint8_t dbus_data; + uint8_t dbus_ddr; + uint8_t cbus_data; + uint8_t cbus_ddr; + char *description; + char * name; +}cable_desc_t; + +extern cable_desc_t *active_cable; + static inline int platform_hwversion(void) { return 0; From 7d45bd4869dc0203b45e87e6262ffbe6b5fd5ce3 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 28 Apr 2018 14:07:10 +0200 Subject: [PATCH 05/14] ibftdi/jtagtap: Remove magic numbers. --- src/platforms/libftdi/jtagtap.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/platforms/libftdi/jtagtap.c b/src/platforms/libftdi/jtagtap.c index bc7ab41..d761d26 100644 --- a/src/platforms/libftdi/jtagtap.c +++ b/src/platforms/libftdi/jtagtap.c @@ -22,7 +22,6 @@ * * Issues: * This code is old, rotten and unsupported. - * Magic numbers everywhere. * Should share interface with swdptap.c or at least clean up... */ @@ -71,7 +70,7 @@ void jtagtap_reset(void) void jtagtap_tms_seq(uint32_t MS, int ticks) { - uint8_t tmp[3] = "\x4B"; + uint8_t tmp[3] = {MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE| MPSSE_READ_NEG, 0, 0}; while(ticks >= 0) { //jtagtap_next(MS & 1, 1); tmp[1] = ticks<7?ticks-1:6; @@ -100,20 +99,20 @@ jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks) tmp = alloca(ticks + 9); if(ticks) { - tmp[index++] = 0x19; + tmp[index++] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG; tmp[index++] = ticks - 1; tmp[index++] = 0; while(ticks--) tmp[index++] = *DI++; } if(rticks) { - tmp[index++] = 0x1B; + tmp[index++] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; tmp[index++] = rticks - 1; tmp[index++] = *DI; } if(final_tms) { - tmp[index++] = 0x4B; + tmp[index++] = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; tmp[index++] = 0; tmp[index++] = (*DI)>>rticks?0x81:0x01; } @@ -139,7 +138,7 @@ jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int tmp = alloca(ticks + 9); rsize = ticks; if(ticks) { - tmp[index++] = 0x39; + tmp[index++] = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG; tmp[index++] = ticks - 1; tmp[index++] = 0; while(ticks--) tmp[index++] = *DI++; @@ -147,14 +146,14 @@ jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int if(rticks) { rsize++; - tmp[index++] = 0x3B; + tmp[index++] = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; tmp[index++] = rticks - 1; tmp[index++] = *DI; } if(final_tms) { rsize++; - tmp[index++] = 0x6B; + tmp[index++] = MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; tmp[index++] = 0; tmp[index++] = (*DI)>>rticks?0x81:0x01; } @@ -190,7 +189,7 @@ jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI) { uint8_t ret; - uint8_t tmp[3] = "\x6B\x00\x00"; + uint8_t tmp[3] = {MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG, 0, 0}; tmp[2] = (dTDI?0x80:0) | (dTMS?0x01:0); // assert(ftdi_write_data(ftdic, tmp, 3) == 3); // while(ftdi_read_data(ftdic, &ret, 1) != 1); From c548e307feac370faeb9131ac0d76109aa6fa3d1 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 28 Apr 2018 14:11:50 +0200 Subject: [PATCH 06/14] libftdi/jtagtap: Clean up code. --- src/platforms/libftdi/jtagtap.c | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/src/platforms/libftdi/jtagtap.c b/src/platforms/libftdi/jtagtap.c index d761d26..c8cb81a 100644 --- a/src/platforms/libftdi/jtagtap.c +++ b/src/platforms/libftdi/jtagtap.c @@ -21,7 +21,6 @@ /* Low level JTAG implementation using FT2232 with libftdi. * * Issues: - * This code is old, rotten and unsupported. * Should share interface with swdptap.c or at least clean up... */ @@ -34,20 +33,8 @@ #include #include "general.h" - -#define PROVIDE_GENERIC_TAP_SEQ -//#define PROVIDE_GENERIC_TAP_TMS_SEQ -//#define PROVIDE_GENERIC_TAP_TDI_TDO_SEQ -//#define PROVIDE_GENERIC_TAP_TDI_SEQ #include "jtagtap.h" -#define ALL_ZERO 0xA0 -#define TCK 0x01 -#define TDI 0x02 -#define TDO 0x04 -#define TMS 0x08 -#define nSRST 0x20 - int jtagtap_init(void) { assert(ftdic != NULL); @@ -66,24 +53,19 @@ void jtagtap_reset(void) jtagtap_soft_reset(); } -#ifndef PROVIDE_GENERIC_TAP_TMS_SEQ 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}; while(ticks >= 0) { - //jtagtap_next(MS & 1, 1); tmp[1] = ticks<7?ticks-1:6; tmp[2] = 0x80 | (MS & 0x7F); -// assert(ftdi_write_data(ftdic, tmp, 3) == 3); platform_buffer_write(tmp, 3); MS >>= 7; ticks -= 7; } } -#endif -#ifndef PROVIDE_GENERIC_TAP_TDI_SEQ void jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks) { @@ -116,12 +98,9 @@ jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks) tmp[index++] = 0; tmp[index++] = (*DI)>>rticks?0x81:0x01; } -// assert(ftdi_write_data(ftdic, tmp, index) == index); platform_buffer_write(tmp, index); } -#endif -#ifndef PROVIDE_GENERIC_TAP_TDI_TDO_SEQ void jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks) { @@ -157,12 +136,9 @@ jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int tmp[index++] = 0; tmp[index++] = (*DI)>>rticks?0x81:0x01; } -// assert(ftdi_write_data(ftdic, tmp, index) == index); platform_buffer_write(tmp, index); -// index = 0; -// while((index += ftdi_read_data(ftdic, tmp + index, rsize-index)) != rsize); platform_buffer_read(tmp, rsize); - /*for(index = 0; index < rsize; index++) + /*for(int index = 0; index < rsize; index++) printf("%02X ", tmp[index]); printf("\n");*/ index = 0; @@ -184,15 +160,12 @@ jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int } /*printf("%02X\n", *DO);*/ } -#endif uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI) { uint8_t ret; uint8_t tmp[3] = {MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG, 0, 0}; tmp[2] = (dTDI?0x80:0) | (dTMS?0x01:0); -// assert(ftdi_write_data(ftdic, tmp, 3) == 3); -// while(ftdi_read_data(ftdic, &ret, 1) != 1); platform_buffer_write(tmp, 3); platform_buffer_read(&ret, 1); From aa938c6dae9d0674e75f35443d20463ce8ba63ac Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 7 May 2018 17:56:51 +0200 Subject: [PATCH 07/14] libftdi/jtagtap: Try harder to initialize Ftdi MPSSE jtag mode. After "mon s" at least the second "mon j" now succeeds again. --- src/platforms/libftdi/jtagtap.c | 28 ++++++++++++++++++++++++++++ src/platforms/libftdi/platform.c | 25 ------------------------- src/platforms/libftdi/swdptap.c | 7 +++++++ 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/platforms/libftdi/jtagtap.c b/src/platforms/libftdi/jtagtap.c index c8cb81a..4857f4c 100644 --- a/src/platforms/libftdi/jtagtap.c +++ b/src/platforms/libftdi/jtagtap.c @@ -38,6 +38,34 @@ int jtagtap_init(void) { assert(ftdic != NULL); + int err = ftdi_usb_purge_buffers(ftdic); + if (err != 0) { + fprintf(stderr, "ftdi_usb_purge_buffer: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + abort(); + } + /* Reset MPSSE controller. */ + err = ftdi_set_bitmode(ftdic, 0, BITMODE_RESET); + if (err != 0) { + fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + return -1;; + } + /* Enable MPSSE controller. Pin directions are set later.*/ + err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE); + if (err != 0) { + fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + return -1;; + } + uint8_t ftdi_init[9] = {TCK_DIVISOR, 0x00, 0x00, SET_BITS_LOW, 0,0, + SET_BITS_HIGH, 0,0}; + ftdi_init[4]= active_cable->dbus_data; + ftdi_init[5]= active_cable->dbus_ddr; + ftdi_init[7]= active_cable->cbus_data; + ftdi_init[8]= active_cable->cbus_ddr; + platform_buffer_write(ftdi_init, 9); + platform_buffer_flush(); /* Go to JTAG mode for SWJ-DP */ for (int i = 0; i <= 50; i++) diff --git a/src/platforms/libftdi/platform.c b/src/platforms/libftdi/platform.c index 43bc68f..d58c9e4 100644 --- a/src/platforms/libftdi/platform.c +++ b/src/platforms/libftdi/platform.c @@ -150,9 +150,6 @@ void platform_init(int argc, char **argv) unsigned index = 0; char *serial = NULL; char * cablename = "ftdi"; - uint8_t ftdi_init[9] = {TCK_DIVISOR, 0x01, 0x00, SET_BITS_LOW, 0,0, - SET_BITS_HIGH, 0,0}; - while((c = getopt(argc, argv, "c:s:")) != -1) { switch(c) { case 'c': @@ -176,15 +173,6 @@ void platform_init(int argc, char **argv) active_cable = &cable_desc[index]; - if (active_cable->dbus_data) - ftdi_init[4]= active_cable->dbus_data; - if (active_cable->dbus_ddr) - ftdi_init[5]= active_cable->dbus_ddr; - if (active_cable->cbus_data) - ftdi_init[7]= active_cable->cbus_data; - if(active_cable->cbus_ddr) - ftdi_init[8]= active_cable->cbus_ddr; - printf("\nBlack Magic Probe (" FIRMWARE_VERSION ")\n"); printf("Copyright (C) 2015 Black Sphere Technologies Ltd.\n"); printf("License GPLv3+: GNU GPL version 3 or later " @@ -223,24 +211,11 @@ void platform_init(int argc, char **argv) err, ftdi_get_error_string(ftdic)); abort(); } - if((err = ftdi_usb_purge_buffers(ftdic)) != 0) { - fprintf(stderr, "ftdi_set_baudrate: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } if((err = ftdi_write_data_set_chunksize(ftdic, BUF_SIZE)) != 0) { fprintf(stderr, "ftdi_write_data_set_chunksize: %d: %s\n", err, ftdi_get_error_string(ftdic)); abort(); } - - if((err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE)) != 0) { - fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", - err, ftdi_get_error_string(ftdic)); - abort(); - } - - assert(ftdi_write_data(ftdic, ftdi_init, 9) == 9); assert(gdb_if_init() == 0); } diff --git a/src/platforms/libftdi/swdptap.c b/src/platforms/libftdi/swdptap.c index c48fb1a..24b2ce3 100644 --- a/src/platforms/libftdi/swdptap.c +++ b/src/platforms/libftdi/swdptap.c @@ -37,6 +37,13 @@ int swdptap_init(void) assert(ftdic != NULL); + /* Reset MPSSE controller. */ + if((err = ftdi_set_bitmode(ftdic, 0, BITMODE_RESET)) != 0) { + fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + abort(); + } + if((err = ftdi_set_bitmode(ftdic, 0xAB, BITMODE_BITBANG)) != 0) { fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", err, ftdi_get_error_string(ftdic)); From de33473535f6e0571598e5e95fd3f33e8a1f1309 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 29 Apr 2018 13:29:45 +0200 Subject: [PATCH 08/14] libftdi/jtagtap: Copy DI direct into the write buffer. --- src/platforms/libftdi/jtagtap.c | 64 ++++++++++++++++----------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/src/platforms/libftdi/jtagtap.c b/src/platforms/libftdi/jtagtap.c index 4857f4c..dd1e158 100644 --- a/src/platforms/libftdi/jtagtap.c +++ b/src/platforms/libftdi/jtagtap.c @@ -97,8 +97,6 @@ jtagtap_tms_seq(uint32_t MS, int ticks) void jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks) { - uint8_t *tmp; - int index = 0; int rticks; if(!ticks) return; @@ -106,35 +104,35 @@ jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks) if(final_tms) ticks--; rticks = ticks & 7; ticks >>= 3; - tmp = alloca(ticks + 9); + uint8_t data[3]; if(ticks) { - tmp[index++] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG; - tmp[index++] = ticks - 1; - tmp[index++] = 0; - while(ticks--) tmp[index++] = *DI++; + data[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG; + data[1] = ticks - 1; + data[2] = 0; + platform_buffer_write(data, 3); + platform_buffer_write(DI, ticks); } if(rticks) { - tmp[index++] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - tmp[index++] = rticks - 1; - tmp[index++] = *DI; + data[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + data[1] = rticks - 1; + data[2] = DI[ticks]; + platform_buffer_write(data, 3); } if(final_tms) { - tmp[index++] = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - tmp[index++] = 0; - tmp[index++] = (*DI)>>rticks?0x81:0x01; + data[0] = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + data[1] = 0; + data[2] = (*DI)>>rticks?0x81:0x01; + platform_buffer_write(data, 3); } - platform_buffer_write(tmp, index); } void jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks) { - uint8_t *tmp; - int index = 0, rsize; - int rticks; + int rsize, rticks; if(!ticks) return; @@ -142,34 +140,34 @@ jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int if(final_tms) ticks--; rticks = ticks & 7; ticks >>= 3; - tmp = alloca(ticks + 9); + uint8_t data[3]; rsize = ticks; if(ticks) { - tmp[index++] = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG; - tmp[index++] = ticks - 1; - tmp[index++] = 0; - while(ticks--) tmp[index++] = *DI++; + data[0] = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG; + data[1] = ticks - 1; + data[2] = 0; + platform_buffer_write(data, 3); + platform_buffer_write(DI, ticks); } if(rticks) { rsize++; - tmp[index++] = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - tmp[index++] = rticks - 1; - tmp[index++] = *DI; + data[0] = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + data[1] = rticks - 1; + data[2] = DI[ticks]; + platform_buffer_write(data, 3); } if(final_tms) { rsize++; - tmp[index++] = MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - tmp[index++] = 0; - tmp[index++] = (*DI)>>rticks?0x81:0x01; + data[0] = MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + data[1] = 0; + data[2] = (*DI)>>rticks?0x81:0x01; + platform_buffer_write(data, 3); } - platform_buffer_write(tmp, index); + uint8_t *tmp = alloca(ticks); + int index = 0; platform_buffer_read(tmp, rsize); - /*for(int index = 0; index < rsize; index++) - printf("%02X ", tmp[index]); - printf("\n");*/ - index = 0; if(final_tms) rsize--; while(rsize--) { From 2ec078cfcfd2a5f384cde1906f0d9aef88821593 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 29 Apr 2018 13:50:29 +0200 Subject: [PATCH 09/14] libftdi/jtagtap.c: Allow NULL as one DI/DO argument jtagtap_tdi_tdo_seq. Implement jtagtap_tdi_seq() by calling jtagtap_tdi_tdo_seq(). --- src/platforms/libftdi/jtagtap.c | 107 +++++++++++++------------------- 1 file changed, 42 insertions(+), 65 deletions(-) diff --git a/src/platforms/libftdi/jtagtap.c b/src/platforms/libftdi/jtagtap.c index dd1e158..d9f2e3b 100644 --- a/src/platforms/libftdi/jtagtap.c +++ b/src/platforms/libftdi/jtagtap.c @@ -94,97 +94,74 @@ jtagtap_tms_seq(uint32_t MS, int ticks) } } -void -jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks) -{ - int rticks; - - if(!ticks) return; - - if(final_tms) ticks--; - rticks = ticks & 7; - ticks >>= 3; - uint8_t data[3]; - - if(ticks) { - data[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG; - data[1] = ticks - 1; - data[2] = 0; - platform_buffer_write(data, 3); - platform_buffer_write(DI, ticks); - } - - if(rticks) { - data[0] = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - data[1] = rticks - 1; - data[2] = DI[ticks]; - platform_buffer_write(data, 3); - } - - if(final_tms) { - data[0] = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - data[1] = 0; - data[2] = (*DI)>>rticks?0x81:0x01; - platform_buffer_write(data, 3); - } -} - void jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks) { int rsize, rticks; if(!ticks) return; + if (!DI && !DO) return; // printf("ticks: %d\n", ticks); if(final_tms) ticks--; rticks = ticks & 7; ticks >>= 3; uint8_t data[3]; + uint8_t cmd = ((DO)? MPSSE_DO_READ : 0) | ((DI)? (MPSSE_DO_WRITE | MPSSE_WRITE_NEG) : 0) | MPSSE_LSB; rsize = ticks; if(ticks) { - data[0] = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_WRITE_NEG; + data[0] = cmd; data[1] = ticks - 1; data[2] = 0; platform_buffer_write(data, 3); - platform_buffer_write(DI, ticks); + if (DI) + platform_buffer_write(DI, ticks); } - if(rticks) { + int index = 0; rsize++; - data[0] = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - data[1] = rticks - 1; - data[2] = DI[ticks]; - platform_buffer_write(data, 3); + data[index++] = cmd | MPSSE_BITMODE; + data[index++] = rticks - 1; + if (DI) + data[index++] = DI[ticks]; + platform_buffer_write(data, index); } - if(final_tms) { + int index = 0; rsize++; - data[0] = MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - data[1] = 0; - data[2] = (*DI)>>rticks?0x81:0x01; - platform_buffer_write(data, 3); + data[index++] = MPSSE_WRITE_TMS | ((DO)? MPSSE_DO_READ : 0) | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + data[index++] = 0; + if (DI) + data[index++] = (*DI)>>rticks?0x81:0x01; + platform_buffer_write(data, index); } - uint8_t *tmp = alloca(ticks); - int index = 0; - platform_buffer_read(tmp, rsize); - if(final_tms) rsize--; + if (DO) { + int index = 0; + uint8_t *tmp = alloca(ticks); + platform_buffer_read(tmp, rsize); + if(final_tms) rsize--; - while(rsize--) { - /*if(rsize) printf("%02X ", tmp[index]);*/ - *DO++ = tmp[index++]; + while(rsize--) { + /*if(rsize) printf("%02X ", tmp[index]);*/ + *DO++ = tmp[index++]; + } + if (rticks == 0) + *DO++ = 0; + if(final_tms) { + rticks++; + *(--DO) >>= 1; + *DO |= tmp[index] & 0x80; + } else DO--; + if(rticks) { + *DO >>= (8-rticks); + } + /*printf("%02X\n", *DO);*/ } - if (rticks == 0) - *DO++ = 0; - if(final_tms) { - rticks++; - *(--DO) >>= 1; - *DO |= tmp[index] & 0x80; - } else DO--; - if(rticks) { - *DO >>= (8-rticks); - } - /*printf("%02X\n", *DO);*/ +} + +void jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks) +{ + return jtagtap_tdi_tdo_seq(NULL, final_tms, DI, ticks); } uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI) From f3cacba2191de35985ea523361c723f8c7de4eeb Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 8 May 2018 19:34:29 +0200 Subject: [PATCH 10/14] libftdi: Flush buffer with detach. --- src/target/target.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/target/target.c b/src/target/target.c index 1882851..559792c 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -294,6 +294,10 @@ void target_detach(target *t) { t->detach(t); t->attached = false; +#if defined(LIBFTDI) +# include "platform.h" + platform_buffer_flush(); +#endif } bool target_check_error(target *t) { return t->check_error(t); } From 992ccf91a99c05f69b92de0e9e76507900d18071 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 29 May 2018 19:33:43 +0200 Subject: [PATCH 11/14] libftdi/swdptap.c: Use MPSSE Mode for bitbanging SWD. --- src/platforms/libftdi/platform.h | 4 ++ src/platforms/libftdi/swdptap.c | 101 +++++++++++++++++++------------ 2 files changed, 67 insertions(+), 38 deletions(-) diff --git a/src/platforms/libftdi/platform.h b/src/platforms/libftdi/platform.h index 7b4f4b9..562f58f 100644 --- a/src/platforms/libftdi/platform.h +++ b/src/platforms/libftdi/platform.h @@ -67,5 +67,9 @@ static inline int platform_hwversion(void) return 0; } +#define MPSSE_TDI 2 +#define MPSSE_TDO 4 +#define MPSSE_TMS 8 + #endif diff --git a/src/platforms/libftdi/swdptap.c b/src/platforms/libftdi/swdptap.c index 24b2ce3..de8270e 100644 --- a/src/platforms/libftdi/swdptap.c +++ b/src/platforms/libftdi/swdptap.c @@ -1,7 +1,7 @@ /* * This file is part of the Black Magic Debug project. * - * Copyright (C) 2011 Black Sphere Technologies Ltd. + * Copyright (C) 2018 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) * Written by Gareth McMullin * * This program is free software: you can redistribute it and/or modify @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -/* Quick hack for bit-banging SW-DP interface over FT2232. - * Intended as proof of concept, not for production. +/* MPSSE bit-banging SW-DP interface over FTDI. + * Slow, but usable. */ #include @@ -31,72 +31,97 @@ static uint8_t olddir = 0; +#define MPSSE_MASK (MPSSE_TDI | MPSSE_TDO | MPSSE_TMS) +#define MPSSE_TD_MASK (MPSSE_TDI | MPSSE_TDO) +#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) { - int err; - - assert(ftdic != NULL); - + int err = ftdi_usb_purge_buffers(ftdic); + if (err != 0) { + fprintf(stderr, "ftdi_usb_purge_buffer: %d: %s\n", + err, ftdi_get_error_string(ftdic)); + abort(); + } /* Reset MPSSE controller. */ - if((err = ftdi_set_bitmode(ftdic, 0, BITMODE_RESET)) != 0) { + err = ftdi_set_bitmode(ftdic, 0, BITMODE_RESET); + if (err != 0) { fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", err, ftdi_get_error_string(ftdic)); - abort(); + return -1;; } - - if((err = ftdi_set_bitmode(ftdic, 0xAB, BITMODE_BITBANG)) != 0) { + /* Enable MPSSE controller. Pin directions are set later.*/ + err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE); + if (err != 0) { fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", err, ftdi_get_error_string(ftdic)); - abort(); + return -1;; } - - assert(ftdi_write_data(ftdic, (void*)"\xAB\xA8", 2) == 2); - olddir = 0; + uint8_t ftdi_init[9] = {TCK_DIVISOR, 0x01, 0x00, SET_BITS_LOW, 0,0, + SET_BITS_HIGH, 0,0}; + ftdi_init[4]= active_cable->dbus_data | MPSSE_MASK; + ftdi_init[5]= active_cable->dbus_ddr & ~MPSSE_TD_MASK; + ftdi_init[7]= active_cable->cbus_data; + ftdi_init[8]= active_cable->cbus_ddr; + platform_buffer_write(ftdi_init, 9); + platform_buffer_flush(); return 0; } static void swdptap_turnaround(uint8_t dir) { - platform_buffer_flush(); - if (dir == olddir) return; olddir = dir; + uint8_t cmd[6]; + int index = 0; - if(dir) /* SWDIO goes to input */ - assert(ftdi_set_bitmode(ftdic, 0xA3, BITMODE_BITBANG) == 0); - + if(dir) { /* SWDIO goes to input */ + cmd[index++] = SET_BITS_LOW; + cmd[index++] = active_cable->dbus_data | MPSSE_MASK; + cmd[index++] = active_cable->dbus_ddr & ~MPSSE_MASK; + } /* One clock cycle */ - ftdi_write_data(ftdic, (void *)"\xAB\xA8", 2); - - if(!dir) /* SWDIO goes to output */ - assert(ftdi_set_bitmode(ftdic, 0xAB, BITMODE_BITBANG) == 0); + cmd[index++] = MPSSE_TMS_SHIFT; + cmd[index++] = 0; + cmd[index++] = 0; + if (!dir) { + cmd[index++] = SET_BITS_LOW; + cmd[index++] = active_cable->dbus_data | MPSSE_MASK; + cmd[index++] = active_cable->dbus_ddr & ~MPSSE_TD_MASK; + } + platform_buffer_write(cmd, index); } bool swdptap_bit_in(void) { - uint8_t ret; - swdptap_turnaround(1); + uint8_t cmd[4]; + int index = 0; - ftdi_read_pins(ftdic, &ret); - ret &= 0x08; - ftdi_write_data(ftdic, (void *)"\xA1\xA0", 2); - - return ret; + cmd[index++] = MPSSE_TMS_IN_PORT; + 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); } void swdptap_bit_out(bool val) { - uint8_t buf[3] = "\xA0\xA1\xA0"; - swdptap_turnaround(0); + uint8_t cmd[3]; - if (val) { - for(int i = 0; i < 3; i++) - buf[i] |= 0x08; - } - platform_buffer_write(buf, 3); + cmd[0] = MPSSE_TMS_SHIFT; + cmd[1] = 0; + cmd[2] = (val)? 1 : 0; + platform_buffer_write(cmd, 3); } From fce25b9fd514a39abfd403d4ab95fb92983e31eb Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 29 May 2018 20:55:30 +0200 Subject: [PATCH 12/14] libftdi/swdptap.c: Substantial speed increase for bitbanging SWD. Provide the swd sequences unrolled. --- src/platforms/libftdi/swdptap.c | 108 +++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-) diff --git a/src/platforms/libftdi/swdptap.c b/src/platforms/libftdi/swdptap.c index de8270e..9df9af8 100644 --- a/src/platforms/libftdi/swdptap.c +++ b/src/platforms/libftdi/swdptap.c @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -/* MPSSE bit-banging SW-DP interface over FTDI. - * Slow, but usable. +/* MPSSE bit-banging SW-DP interface over FTDI with loop unrolled. + * Speed is sensible. */ #include @@ -125,3 +125,107 @@ void swdptap_bit_out(bool val) platform_buffer_write(cmd, 3); } +bool swdptap_seq_in_parity(uint32_t *res, int ticks) +{ + int index = ticks + 1; + uint8_t cmd[4]; + unsigned int parity = 0; + + cmd[0] = MPSSE_TMS_IN_PORT; + cmd[1] = MPSSE_TMS_SHIFT; + cmd[2] = 0; + cmd[3] = 0; + swdptap_turnaround(1); + while (index--) { + platform_buffer_write(cmd, 4); + } + uint8_t data[33]; + unsigned int ret = 0; + platform_buffer_read(data, ticks + 1); + if (data[ticks] & 0x08) + parity ^= 1; + while (ticks--) { + if (data[ticks] & MPSSE_TMS_IN_PIN) { + parity ^= 1; + ret |= (1 << ticks); + } + } + *res = ret; + return parity; +} + +uint32_t swdptap_seq_in(int ticks) +{ + int index = ticks; + uint8_t cmd[4]; + + cmd[0] = MPSSE_TMS_IN_PORT; + cmd[1] = MPSSE_TMS_SHIFT; + cmd[2] = 0; + cmd[3] = 0; + + swdptap_turnaround(1); + while (index--) { + platform_buffer_write(cmd, 4); + } + uint8_t data[32]; + uint32_t ret = 0; + platform_buffer_read(data, ticks); + while (ticks--) { + if (data[ticks] & MPSSE_TMS_IN_PIN) + ret |= (1 << ticks); + } + return ret; +} + +void swdptap_seq_out(uint32_t MS, int ticks) +{ + uint8_t cmd[15]; + uint index = 0; + swdptap_turnaround(0); + while (ticks) { + cmd[index++] = MPSSE_TMS_SHIFT; + if (ticks >= 7) { + cmd[index++] = 6; + cmd[index++] = MS & 0x7f; + MS >>= 7; + ticks -= 7; + } else { + cmd[index++] = ticks - 1; + cmd[index++] = MS & 0x7f; + ticks = 0; + } + } + platform_buffer_write(cmd, index); +} + +void swdptap_seq_out_parity(uint32_t MS, int ticks) +{ + uint8_t parity = 0; + int steps = ticks; + uint8_t cmd[18]; + uint index = 0; + uint32_t data = MS; + swdptap_turnaround(0); + while (steps) { + cmd[index++] = MPSSE_TMS_SHIFT; + if (steps >= 7) { + cmd[index++] = 6; + cmd[index++] = data & 0x7f; + data >>= 7; + steps -= 7; + } else { + cmd[index++] = steps - 1; + cmd[index++] = data & 0x7f; + steps = 0; + } + } + while (ticks--) { + parity ^= MS; + MS >>= 1; + } + cmd[index++] = MPSSE_TMS_SHIFT; + cmd[index++] = 0; + cmd[index++] = parity; + platform_buffer_write(cmd, index); +} From df05d7ce7b666bb31ce45a47c19d96e5c2801a39 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 May 2018 16:55:41 +0200 Subject: [PATCH 13/14] libftdi: Allow device specific port/pin to read SWD bitbanged. Gracefully abort swd scan if devices can not do SWD. Best effort to indicated SWD capability on existing cables and add descriptions for the cables. --- src/platforms/libftdi/platform.c | 34 ++++++++++++++++++++++++++++++++ src/platforms/libftdi/platform.h | 2 ++ src/platforms/libftdi/swdptap.c | 21 ++++++++++---------- src/target/adiv5_swdp.c | 3 ++- 4 files changed, 49 insertions(+), 11 deletions(-) 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); From 2657aa6fbb4fd5878fb4313f3096567a3eb4c198 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 May 2018 18:55:50 +0200 Subject: [PATCH 14/14] libftdi: Allow more flexible Swd Read/Write Switching. --- src/platforms/libftdi/platform.c | 1 + src/platforms/libftdi/platform.h | 3 +++ src/platforms/libftdi/swdptap.c | 8 ++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/platforms/libftdi/platform.c b/src/platforms/libftdi/platform.c index 83683c7..3c52de9 100644 --- a/src/platforms/libftdi/platform.c +++ b/src/platforms/libftdi/platform.c @@ -83,6 +83,7 @@ cable_desc_t cable_desc[] = { .cbus_ddr = 0x02, .bitbang_tms_in_port_cmd = GET_BITS_LOW, .bitbang_tms_in_pin = MPSSE_TDO, /* keep bit 5 low*/ + .bitbang_swd_dbus_read_data = 0x02, .name = "ftdiswd" }, { diff --git a/src/platforms/libftdi/platform.h b/src/platforms/libftdi/platform.h index b3fae42..b669ad0 100644 --- a/src/platforms/libftdi/platform.h +++ b/src/platforms/libftdi/platform.h @@ -58,6 +58,9 @@ typedef struct cable_desc_s { uint8_t cbus_ddr; uint8_t bitbang_tms_in_port_cmd; uint8_t bitbang_tms_in_pin; + uint8_t bitbang_swd_dbus_read_data; + /* bitbang_swd_dbus_read_data is same as dbus_data, + * as long as CBUS is not involved.*/ char *description; char * name; }cable_desc_t; diff --git a/src/platforms/libftdi/swdptap.c b/src/platforms/libftdi/swdptap.c index 5d6279c..150083b 100644 --- a/src/platforms/libftdi/swdptap.c +++ b/src/platforms/libftdi/swdptap.c @@ -84,8 +84,12 @@ static void swdptap_turnaround(uint8_t dir) if(dir) { /* SWDIO goes to input */ cmd[index++] = SET_BITS_LOW; - cmd[index++] = active_cable->dbus_data | MPSSE_MASK; - cmd[index++] = active_cable->dbus_ddr & ~MPSSE_MASK; + if (active_cable->bitbang_swd_dbus_read_data) + cmd[index] = active_cable->bitbang_swd_dbus_read_data; + else + cmd[index] = active_cable->dbus_data; + index++; + cmd[index++] = active_cable->dbus_ddr & ~MPSSE_MASK; } /* One clock cycle */ cmd[index++] = MPSSE_TMS_SHIFT;