hosted: add libftdi implementation, remove old implementation.

This commit is contained in:
Uwe Bonnes 2020-04-28 16:54:56 +02:00
parent ab7991c3a6
commit ef816e3183
8 changed files with 111 additions and 162 deletions

View File

@ -2,6 +2,8 @@ SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DENABLE_DEBUG -DPLATFORM_HAS_DEBUG CFLAGS += -DENABLE_DEBUG -DPLATFORM_HAS_DEBUG
CFLAGS +=-I ./target -I./platforms/pc CFLAGS +=-I ./target -I./platforms/pc
LDFLAGS += -lusb-1.0 LDFLAGS += -lusb-1.0
CFLAGS += $(shell pkg-config --cflags libftdi1)
LDFLAGS += $(shell pkg-config --libs libftdi1)
ifneq (, $(findstring mingw, $(SYS))) ifneq (, $(findstring mingw, $(SYS)))
SRC += serial_win.c SRC += serial_win.c
LDFLAGS += -lws2_32 LDFLAGS += -lws2_32
@ -15,4 +17,5 @@ VPATH += platforms/pc
SRC += timing.c cl_utils.c utils.c libusb_utils.c SRC += timing.c cl_utils.c utils.c libusb_utils.c
SRC += stlinkv2.c SRC += stlinkv2.c
SRC += bmp_remote.c remote_swdptap.c remote_jtagtap.c SRC += bmp_remote.c remote_swdptap.c remote_jtagtap.c
SRC += ftdi_bmp.c libftdi_swdptap.c libftdi_jtagtap.c
PC_HOSTED = 1 PC_HOSTED = 1

View File

@ -27,9 +27,9 @@
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
struct ftdi_context *ftdic; #include "ftdi_bmp.h"
#include "cl_utils.h" struct ftdi_context *ftdic;
#define BUF_SIZE 4096 #define BUF_SIZE 4096
static uint8_t outbuf[BUF_SIZE]; static uint8_t outbuf[BUF_SIZE];
@ -181,39 +181,18 @@ cable_desc_t cable_desc[] = {
}, },
}; };
int platform_adiv5_swdp_scan(void) int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
{ {
return adiv5_swdp_scan();
}
int platform_jtag_scan(const uint8_t *lrlens)
{
return jtag_scan(lrlens);
}
int platform_jtag_dp_init()
{
return 0;
}
void platform_init(int argc, char **argv)
{
BMP_CL_OPTIONS_t cl_opts = {0};
cl_opts.opt_idstring = "Blackmagic Debug Probe for FTDI/MPSSE";
cl_opts.opt_cable = "ftdi";
cl_init(&cl_opts, argc, argv);
int err; int err;
unsigned index = 0; unsigned index = 0;
int ret = -1;
for(index = 0; index < sizeof(cable_desc)/sizeof(cable_desc[0]); for(index = 0; index < sizeof(cable_desc)/sizeof(cable_desc[0]);
index++) index++)
if (strcmp(cable_desc[index].name, cl_opts.opt_cable) == 0) if (strcmp(cable_desc[index].name, cl_opts->opt_cable) == 0)
break; break;
if (index == sizeof(cable_desc)/sizeof(cable_desc[0])){ if (index == sizeof(cable_desc)/sizeof(cable_desc[0])){
fprintf(stderr, "No cable matching %s found\n", cl_opts.opt_cable); fprintf(stderr, "No cable matching %s found\n", cl_opts->opt_cable);
exit(-1); return -1;
} }
active_cable = &cable_desc[index]; active_cable = &cable_desc[index];
@ -233,6 +212,7 @@ void platform_init(int argc, char **argv)
ftdi_get_error_string(ftdic)); ftdi_get_error_string(ftdic));
abort(); abort();
} }
info->ftdic = ftdic;
if((err = ftdi_set_interface(ftdic, active_cable->interface)) != 0) { if((err = ftdi_set_interface(ftdic, active_cable->interface)) != 0) {
fprintf(stderr, "ftdi_set_interface: %d: %s\n", fprintf(stderr, "ftdi_set_interface: %d: %s\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
@ -240,7 +220,7 @@ void platform_init(int argc, char **argv)
} }
if((err = ftdi_usb_open_desc( if((err = ftdi_usb_open_desc(
ftdic, active_cable->vendor, active_cable->product, ftdic, active_cable->vendor, active_cable->product,
active_cable->description, cl_opts.opt_serial)) != 0) { active_cable->description, cl_opts->opt_serial)) != 0) {
fprintf(stderr, "unable to open ftdi device: %d (%s)\n", fprintf(stderr, "unable to open ftdi device: %d (%s)\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
goto error_1; goto error_1;
@ -261,57 +241,47 @@ void platform_init(int argc, char **argv)
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
goto error_2; goto error_2;
} }
if (cl_opts.opt_mode != BMP_MODE_DEBUG) { return 0;
ret = cl_execute(&cl_opts);
} else {
assert(gdb_if_init() == 0);
return;
}
error_2: error_2:
ftdi_usb_close(ftdic); ftdi_usb_close(ftdic);
error_1: error_1:
ftdi_free(ftdic); ftdi_free(ftdic);
exit(ret); return -1;
} }
void platform_srst_set_val(bool assert) void libftdi_srst_set_val(bool assert)
{ {
(void)assert; (void)assert;
platform_buffer_flush(); libftdi_buffer_flush();
} }
bool platform_srst_get_val(void) { return false; } bool libftdi_srst_get_val(void) { return false; }
void platform_buffer_flush(void) void libftdi_buffer_flush(void)
{ {
assert(ftdi_write_data(ftdic, outbuf, bufptr) == bufptr); assert(ftdi_write_data(ftdic, outbuf, bufptr) == bufptr);
// printf("FT2232 platform_buffer flush: %d bytes\n", bufptr); // printf("FT2232 libftdi_buffer flush: %d bytes\n", bufptr);
bufptr = 0; bufptr = 0;
} }
int platform_buffer_write(const uint8_t *data, int size) int libftdi_buffer_write(const uint8_t *data, int size)
{ {
if((bufptr + size) / BUF_SIZE > 0) platform_buffer_flush(); if((bufptr + size) / BUF_SIZE > 0) libftdi_buffer_flush();
memcpy(outbuf + bufptr, data, size); memcpy(outbuf + bufptr, data, size);
bufptr += size; bufptr += size;
return size; return size;
} }
int platform_buffer_read(uint8_t *data, int size) int libftdi_buffer_read(uint8_t *data, int size)
{ {
int index = 0; int index = 0;
outbuf[bufptr++] = SEND_IMMEDIATE; outbuf[bufptr++] = SEND_IMMEDIATE;
platform_buffer_flush(); libftdi_buffer_flush();
while((index += ftdi_read_data(ftdic, data + index, size-index)) != size); while((index += ftdi_read_data(ftdic, data + index, size-index)) != size);
return size; return size;
} }
const char *platform_target_voltage(void) const char *libftdi_target_voltage(void)
{ {
return "not supported"; return "not supported";
} }
void platform_adiv5_dp_defaults(void *arg)
{
(void) arg;
}

View File

@ -18,34 +18,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __PLATFORM_H #ifndef __FTDI_BMP_H
#define __PLATFORM_H #define __FTDI_BMP_H
#include <libftdi1/ftdi.h> #include "cl_utils.h"
#include "swdptap.h"
#include "timing.h" #include "jtagtap.h"
#ifndef _WIN32
# include <alloca.h>
#else
# ifndef alloca
# define alloca __builtin_alloca
# endif
#endif
#define FT2232_VID 0x0403
#define FT2232_PID 0x6010
#define PLATFORM_IDENT() "FTDI/MPSSE"
#define SET_RUN_STATE(state)
#define SET_IDLE_STATE(state)
#define SET_ERROR_STATE(state)
extern struct ftdi_context *ftdic;
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 { typedef struct cable_desc_s {
int vendor; int vendor;
@ -65,15 +43,19 @@ typedef struct cable_desc_s {
}cable_desc_t; }cable_desc_t;
extern cable_desc_t *active_cable; extern cable_desc_t *active_cable;
extern struct ftdi_context *ftdic;
static inline int platform_hwversion(void) int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info);
{
return 0; int libftdi_swdptap_init(swd_proc_t *swd_proc);
} int libftdi_jtagtap_init(jtag_proc_t *jtag_proc);
void libftdi_buffer_flush(void);
int libftdi_buffer_write(const uint8_t *data, int size);
int libftdi_buffer_read(uint8_t *data, int size);
const char *libftdi_target_voltage(void);
#define MPSSE_TDI 2 #define MPSSE_TDI 2
#define MPSSE_TDO 4 #define MPSSE_TDO 4
#define MPSSE_TMS 8 #define MPSSE_TMS 8
#endif #endif

View File

@ -31,9 +31,10 @@
#include <assert.h> #include <assert.h>
#include "general.h" #include "general.h"
#include "jtagtap.h" #include "ftdi_bmp.h"
jtag_proc_t jtag_proc; extern cable_desc_t *active_cable;
extern struct ftdi_context *ftdic;
static void jtagtap_reset(void); static void jtagtap_reset(void);
static void jtagtap_tms_seq(uint32_t MS, int ticks); static void jtagtap_tms_seq(uint32_t MS, int ticks);
@ -43,7 +44,7 @@ static void jtagtap_tdi_seq(
const uint8_t final_tms, const uint8_t *DI, int ticks); const uint8_t final_tms, const uint8_t *DI, int ticks);
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI); static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI);
int platform_jtagtap_init(void) int libftdi_jtagtap_init(jtag_proc_t *jtag_proc)
{ {
assert(ftdic != NULL); assert(ftdic != NULL);
int err = ftdi_usb_purge_buffers(ftdic); int err = ftdi_usb_purge_buffers(ftdic);
@ -57,14 +58,14 @@ int platform_jtagtap_init(void)
if (err != 0) { if (err != 0) {
fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", fprintf(stderr, "ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
return -1;; return -1;
} }
/* Enable MPSSE controller. Pin directions are set later.*/ /* Enable MPSSE controller. Pin directions are set later.*/
err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE); err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE);
if (err != 0) { if (err != 0) {
fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", fprintf(stderr, "ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
return -1;; return -1;
} }
uint8_t ftdi_init[9] = {TCK_DIVISOR, 0x00, 0x00, SET_BITS_LOW, 0,0, uint8_t ftdi_init[9] = {TCK_DIVISOR, 0x00, 0x00, SET_BITS_LOW, 0,0,
SET_BITS_HIGH, 0,0}; SET_BITS_HIGH, 0,0};
@ -72,37 +73,32 @@ int platform_jtagtap_init(void)
ftdi_init[5]= active_cable->dbus_ddr; ftdi_init[5]= active_cable->dbus_ddr;
ftdi_init[7]= active_cable->cbus_data; ftdi_init[7]= active_cable->cbus_data;
ftdi_init[8]= active_cable->cbus_ddr; ftdi_init[8]= active_cable->cbus_ddr;
platform_buffer_write(ftdi_init, 9); libftdi_buffer_write(ftdi_init, 9);
platform_buffer_flush(); libftdi_buffer_flush();
jtag_proc.jtagtap_reset = jtagtap_reset; jtag_proc->jtagtap_reset = jtagtap_reset;
jtag_proc.jtagtap_next =jtagtap_next; jtag_proc->jtagtap_next =jtagtap_next;
jtag_proc.jtagtap_tms_seq = jtagtap_tms_seq; jtag_proc->jtagtap_tms_seq = jtagtap_tms_seq;
jtag_proc.jtagtap_tdi_tdo_seq = jtagtap_tdi_tdo_seq; jtag_proc->jtagtap_tdi_tdo_seq = jtagtap_tdi_tdo_seq;
jtag_proc.jtagtap_tdi_seq = jtagtap_tdi_seq; jtag_proc->jtagtap_tdi_seq = jtagtap_tdi_seq;
/* Go to JTAG mode for SWJ-DP */
for (int i = 0; i <= 50; i++)
jtagtap_next(1, 0); /* Reset SW-DP */
jtagtap_tms_seq(0xE73C, 16); /* SWD to JTAG sequence */
jtagtap_soft_reset();
return 0; return 0;
} }
void jtagtap_reset(void) static void jtagtap_reset(void)
{ {
jtagtap_soft_reset(); jtagtap_soft_reset();
} }
static void jtagtap_tms_seq(uint32_t MS, int ticks) 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}; uint8_t tmp[3] = {
MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE| MPSSE_READ_NEG, 0, 0};
while(ticks >= 0) { while(ticks >= 0) {
tmp[1] = ticks<7?ticks-1:6; tmp[1] = ticks<7?ticks-1:6;
tmp[2] = 0x80 | (MS & 0x7F); tmp[2] = 0x80 | (MS & 0x7F);
platform_buffer_write(tmp, 3); libftdi_buffer_write(tmp, 3);
MS >>= 7; ticks -= 7; MS >>= 7; ticks -= 7;
} }
} }
@ -120,15 +116,16 @@ static void jtagtap_tdi_tdo_seq(
rticks = ticks & 7; rticks = ticks & 7;
ticks >>= 3; ticks >>= 3;
uint8_t data[3]; uint8_t data[3];
uint8_t cmd = ((DO)? MPSSE_DO_READ : 0) | ((DI)? (MPSSE_DO_WRITE | MPSSE_WRITE_NEG) : 0) | MPSSE_LSB; uint8_t cmd = ((DO)? MPSSE_DO_READ : 0) |
((DI)? (MPSSE_DO_WRITE | MPSSE_WRITE_NEG) : 0) | MPSSE_LSB;
rsize = ticks; rsize = ticks;
if(ticks) { if(ticks) {
data[0] = cmd; data[0] = cmd;
data[1] = ticks - 1; data[1] = ticks - 1;
data[2] = 0; data[2] = 0;
platform_buffer_write(data, 3); libftdi_buffer_write(data, 3);
if (DI) if (DI)
platform_buffer_write(DI, ticks); libftdi_buffer_write(DI, ticks);
} }
if(rticks) { if(rticks) {
int index = 0; int index = 0;
@ -137,21 +134,22 @@ static void jtagtap_tdi_tdo_seq(
data[index++] = rticks - 1; data[index++] = rticks - 1;
if (DI) if (DI)
data[index++] = DI[ticks]; data[index++] = DI[ticks];
platform_buffer_write(data, index); libftdi_buffer_write(data, index);
} }
if(final_tms) { if(final_tms) {
int index = 0; int index = 0;
rsize++; rsize++;
data[index++] = MPSSE_WRITE_TMS | ((DO)? MPSSE_DO_READ : 0) | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; data[index++] = MPSSE_WRITE_TMS | ((DO)? MPSSE_DO_READ : 0) |
MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG;
data[index++] = 0; data[index++] = 0;
if (DI) if (DI)
data[index++] = (DI[ticks]) >> rticks?0x81 : 0x01; data[index++] = (DI[ticks]) >> rticks?0x81 : 0x01;
platform_buffer_write(data, index); libftdi_buffer_write(data, index);
} }
if (DO) { if (DO) {
int index = 0; int index = 0;
uint8_t *tmp = alloca(ticks); uint8_t *tmp = alloca(ticks);
platform_buffer_read(tmp, rsize); libftdi_buffer_read(tmp, rsize);
if(final_tms) rsize--; if(final_tms) rsize--;
while(rsize--) { while(rsize--) {
@ -181,10 +179,11 @@ static void jtagtap_tdi_seq(
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI) static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI)
{ {
uint8_t ret; uint8_t ret;
uint8_t tmp[3] = {MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG, 0, 0}; 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); tmp[2] = (dTDI?0x80:0) | (dTMS?0x01:0);
platform_buffer_write(tmp, 3); libftdi_buffer_write(tmp, 3);
platform_buffer_read(&ret, 1); libftdi_buffer_read(&ret, 1);
ret &= 0x80; ret &= 0x80;
@ -192,4 +191,3 @@ static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI)
return ret; return ret;
} }

View File

@ -26,7 +26,7 @@
#include <assert.h> #include <assert.h>
#include "general.h" #include "general.h"
#include "swdptap.h" #include "ftdi_bmp.h"
static uint8_t olddir = 0; static uint8_t olddir = 0;
@ -40,9 +40,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);
swd_proc_t swd_proc; int libftdi_swdptap_init(swd_proc_t *swd_proc)
int platform_swdptap_init(void)
{ {
if (!active_cable->bitbang_tms_in_pin) { if (!active_cable->bitbang_tms_in_pin) {
DEBUG("SWD not possible or missing item in cable description.\n"); DEBUG("SWD not possible or missing item in cable description.\n");
@ -52,21 +50,21 @@ int platform_swdptap_init(void)
if (err != 0) { if (err != 0) {
fprintf(stderr, "ftdi_usb_purge_buffer: %d: %s\n", fprintf(stderr, "ftdi_usb_purge_buffer: %d: %s\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
abort(); return -1;
} }
/* Reset MPSSE controller. */ /* Reset MPSSE controller. */
err = ftdi_set_bitmode(ftdic, 0, BITMODE_RESET); err = ftdi_set_bitmode(ftdic, 0, BITMODE_RESET);
if (err != 0) { if (err != 0) {
fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", fprintf(stderr, "ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
return -1;; return -1;
} }
/* Enable MPSSE controller. Pin directions are set later.*/ /* Enable MPSSE controller. Pin directions are set later.*/
err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE); err = ftdi_set_bitmode(ftdic, 0, BITMODE_MPSSE);
if (err != 0) { if (err != 0) {
fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", fprintf(stderr, "ftdi_set_bitmode: %d: %s\n",
err, ftdi_get_error_string(ftdic)); err, ftdi_get_error_string(ftdic));
return -1;; return -1;
} }
uint8_t ftdi_init[9] = {TCK_DIVISOR, 0x01, 0x00, SET_BITS_LOW, 0,0, uint8_t ftdi_init[9] = {TCK_DIVISOR, 0x01, 0x00, SET_BITS_LOW, 0,0,
SET_BITS_HIGH, 0,0}; SET_BITS_HIGH, 0,0};
@ -74,13 +72,13 @@ int platform_swdptap_init(void)
ftdi_init[5]= active_cable->dbus_ddr & ~MPSSE_TD_MASK; ftdi_init[5]= active_cable->dbus_ddr & ~MPSSE_TD_MASK;
ftdi_init[7]= active_cable->cbus_data; ftdi_init[7]= active_cable->cbus_data;
ftdi_init[8]= active_cable->cbus_ddr; ftdi_init[8]= active_cable->cbus_ddr;
platform_buffer_write(ftdi_init, 9); libftdi_buffer_write(ftdi_init, 9);
platform_buffer_flush(); libftdi_buffer_flush();
swd_proc.swdptap_seq_in = swdptap_seq_in; swd_proc->swdptap_seq_in = swdptap_seq_in;
swd_proc.swdptap_seq_in_parity = swdptap_seq_in_parity; swd_proc->swdptap_seq_in_parity = swdptap_seq_in_parity;
swd_proc.swdptap_seq_out = swdptap_seq_out; swd_proc->swdptap_seq_out = swdptap_seq_out;
swd_proc.swdptap_seq_out_parity = swdptap_seq_out_parity; swd_proc->swdptap_seq_out_parity = swdptap_seq_out_parity;
return 0; return 0;
} }
@ -111,7 +109,7 @@ static void swdptap_turnaround(uint8_t dir)
cmd[index++] = active_cable->dbus_data | MPSSE_MASK; cmd[index++] = active_cable->dbus_data | MPSSE_MASK;
cmd[index++] = active_cable->dbus_ddr & ~MPSSE_TD_MASK; cmd[index++] = active_cable->dbus_ddr & ~MPSSE_TD_MASK;
} }
platform_buffer_write(cmd, index); libftdi_buffer_write(cmd, index);
} }
static bool swdptap_seq_in_parity(uint32_t *res, int ticks) static bool swdptap_seq_in_parity(uint32_t *res, int ticks)
@ -126,11 +124,11 @@ static bool swdptap_seq_in_parity(uint32_t *res, int ticks)
cmd[3] = 0; cmd[3] = 0;
swdptap_turnaround(1); swdptap_turnaround(1);
while (index--) { while (index--) {
platform_buffer_write(cmd, 4); libftdi_buffer_write(cmd, 4);
} }
uint8_t data[33]; uint8_t data[33];
unsigned int ret = 0; unsigned int ret = 0;
platform_buffer_read(data, ticks + 1); libftdi_buffer_read(data, ticks + 1);
if (data[ticks] & active_cable->bitbang_tms_in_pin) if (data[ticks] & active_cable->bitbang_tms_in_pin)
parity ^= 1; parity ^= 1;
while (ticks--) { while (ticks--) {
@ -155,11 +153,11 @@ static uint32_t swdptap_seq_in(int ticks)
swdptap_turnaround(1); swdptap_turnaround(1);
while (index--) { while (index--) {
platform_buffer_write(cmd, 4); libftdi_buffer_write(cmd, 4);
} }
uint8_t data[32]; uint8_t data[32];
uint32_t ret = 0; uint32_t ret = 0;
platform_buffer_read(data, ticks); libftdi_buffer_read(data, ticks);
while (ticks--) { while (ticks--) {
if (data[ticks] & active_cable->bitbang_tms_in_pin) if (data[ticks] & active_cable->bitbang_tms_in_pin)
ret |= (1 << ticks); ret |= (1 << ticks);
@ -185,7 +183,7 @@ static void swdptap_seq_out(uint32_t MS, int ticks)
ticks = 0; ticks = 0;
} }
} }
platform_buffer_write(cmd, index); libftdi_buffer_write(cmd, index);
} }
static void swdptap_seq_out_parity(uint32_t MS, int ticks) static void swdptap_seq_out_parity(uint32_t MS, int ticks)
@ -216,5 +214,5 @@ static void swdptap_seq_out_parity(uint32_t MS, int ticks)
cmd[index++] = MPSSE_TMS_SHIFT; cmd[index++] = MPSSE_TMS_SHIFT;
cmd[index++] = 0; cmd[index++] = 0;
cmd[index++] = parity; cmd[index++] = parity;
platform_buffer_write(cmd, index); libftdi_buffer_write(cmd, index);
} }

View File

@ -34,6 +34,7 @@
#include "bmp_remote.h" #include "bmp_remote.h"
#include "stlinkv2.h" #include "stlinkv2.h"
#include "ftdi_bmp.h"
#define VENDOR_ID_BMP 0x1d50 #define VENDOR_ID_BMP 0x1d50
#define PRODUCT_ID_BMP 0x6018 #define PRODUCT_ID_BMP 0x6018
@ -215,6 +216,13 @@ void platform_init(int argc, char **argv)
} }
if (cl_opts.opt_device) { if (cl_opts.opt_device) {
info.bmp_type = BMP_TYPE_BMP; info.bmp_type = BMP_TYPE_BMP;
} else if (cl_opts.opt_cable) {
/* check for libftdi devices*/
res = ftdi_bmp_init(&cl_opts, &info);
if (res)
exit(-1);
else
info.bmp_type = BMP_TYPE_LIBFTDI;
} else if (find_debuggers(&cl_opts, &info)) { } else if (find_debuggers(&cl_opts, &info)) {
exit(-1); exit(-1);
} }
@ -231,6 +239,8 @@ void platform_init(int argc, char **argv)
if (stlink_init( &info)) if (stlink_init( &info))
exit(-1); exit(-1);
break; break;
case BMP_TYPE_LIBFTDI:
break;
default: default:
exit(-1); exit(-1);
} }
@ -248,6 +258,9 @@ int platform_adiv5_swdp_scan(void)
{ {
switch (info.bmp_type) { switch (info.bmp_type) {
case BMP_TYPE_BMP: case BMP_TYPE_BMP:
case BMP_TYPE_LIBFTDI:
return adiv5_swdp_scan();
break;
case BMP_TYPE_STLINKV2: case BMP_TYPE_STLINKV2:
{ {
target_list_free(); target_list_free();
@ -274,6 +287,8 @@ int platform_swdptap_init(void)
case BMP_TYPE_STLINKV2: case BMP_TYPE_STLINKV2:
return 0; return 0;
break; break;
case BMP_TYPE_LIBFTDI:
return libftdi_swdptap_init(&swd_proc);
default: default:
return -1; return -1;
} }
@ -284,6 +299,8 @@ int platform_jtag_scan(const uint8_t *lrlens)
{ {
switch (info.bmp_type) { switch (info.bmp_type) {
case BMP_TYPE_BMP: case BMP_TYPE_BMP:
case BMP_TYPE_LIBFTDI:
return jtag_scan(lrlens);
case BMP_TYPE_STLINKV2: case BMP_TYPE_STLINKV2:
return jtag_scan_stlinkv2(&info, lrlens); return jtag_scan_stlinkv2(&info, lrlens);
default: default:
@ -299,6 +316,8 @@ int platform_jtagtap_init(void)
return remote_jtagtap_init(&jtag_proc); return remote_jtagtap_init(&jtag_proc);
case BMP_TYPE_STLINKV2: case BMP_TYPE_STLINKV2:
return 0; return 0;
case BMP_TYPE_LIBFTDI:
return libftdi_jtagtap_init(&jtag_proc);
default: default:
return -1; return -1;
} }
@ -319,6 +338,8 @@ int platform_jtag_dp_init(ADIv5_DP_t *dp)
{ {
switch (info.bmp_type) { switch (info.bmp_type) {
case BMP_TYPE_BMP: case BMP_TYPE_BMP:
case BMP_TYPE_LIBFTDI:
return 0;
case BMP_TYPE_STLINKV2: case BMP_TYPE_STLINKV2:
return stlink_jtag_dp_init(dp); return stlink_jtag_dp_init(dp);
default: default:
@ -336,7 +357,7 @@ char *platform_ident(void)
return "BMP"; return "BMP";
case BMP_TYPE_STLINKV2: case BMP_TYPE_STLINKV2:
return "STLINKV2"; return "STLINKV2";
case BMP_TYPE_LIBFTDI: case BMP_TYPE_LIBFTDI:
return "LIBFTDI"; return "LIBFTDI";
case BMP_TYPE_CMSIS_DAP: case BMP_TYPE_CMSIS_DAP:
return "CMSIS_DAP"; return "CMSIS_DAP";
@ -353,6 +374,8 @@ const char *platform_target_voltage(void)
return remote_target_voltage(); return remote_target_voltage();
case BMP_TYPE_STLINKV2: case BMP_TYPE_STLINKV2:
return stlink_target_voltage(&info); return stlink_target_voltage(&info);
case BMP_TYPE_LIBFTDI:
return libftdi_target_voltage();
default: default:
break; break;
} }
@ -387,6 +410,8 @@ bool platform_srst_get_val(void)
void platform_buffer_flush(void) void platform_buffer_flush(void)
{ {
switch (info.bmp_type) { switch (info.bmp_type) {
case BMP_TYPE_LIBFTDI:
return libftdi_buffer_flush();
default: default:
break; break;
} }

View File

@ -1,13 +0,0 @@
SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DENABLE_DEBUG
CFLAGS += $(shell pkg-config --cflags libftdi1)
LDFLAGS += $(shell pkg-config --libs libftdi1)
ifneq (, $(findstring mingw, $(SYS)))
LDFLAGS += -lusb-1.0 -lws2_32
else ifneq (, $(findstring cygwin, $(SYS)))
LDFLAGS += -lusb-1.0 -lws2_32
endif
VPATH += platforms/pc
SRC += timing.c cl_utils.c utils.c
CFLAGS +=-I ./target -I./platforms/pc
PC_HOSTED = 1

View File

@ -1,14 +0,0 @@
Compiling on windows
You can crosscompile blackmagic for windows with mingw or on windows
with cygwin. For compilation, headers for libftdi1 and libusb-1.0 are
needed. For running, libftdi1.dll and libusb-1.0.dll are needed and
the executable must be able to find them. Mingw on cygwin does not provide
a libftdi package yet.
To prepare libusb access to the ftdi device, run zadig https://zadig.akeo.ie/.
Choose WinUSB(libusb-1.0) for the BMP Ftdi device.
Running cygwin/blackmagic in a cygwin console, the program does not react
on ^C. In another console, run "ps ax" to find the WINPID of the process
and then "taskkill /F ?PID (WINPID)".