hosted: add libftdi implementation, remove old implementation.
This commit is contained in:
parent
ab7991c3a6
commit
ef816e3183
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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:
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
|
@ -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)".
|
|
Loading…
Reference in New Issue