Merge branch 'remotes/openocd/master' into riscv64

Merged 1025be363e

Conflicts:
	src/flash/nor/Makefile.am
	src/rtos/Makefile.am
	src/rtos/rtos.c
	src/target/Makefile.am
	src/target/target.c
	src/target/target_type.h

Doesn't build yet, but I fixed the conflicts that git pointed out.
This commit is contained in:
Tim Newsome
2017-06-13 11:52:50 -07:00
303 changed files with 17138 additions and 10591 deletions
+40 -54
View File
@@ -1,86 +1,72 @@
include $(top_srcdir)/common.mk
noinst_LTLIBRARIES += %D%/libjtag.la
METASOURCES = AUTO
noinst_LTLIBRARIES = libjtag.la
JTAG_SRCS =
%C%_libjtag_la_LIBADD =
SUBDIRS =
DRIVERFILES =
libjtag_la_LIBADD =
CLEANFILES =
BUILT_SOURCES =
BUILT_SOURCES += minidriver_imp.h
CLEANFILES += minidriver_imp.h
BUILT_SOURCES += %D%/minidriver_imp.h
CLEANFILES += %D%/minidriver_imp.h
if MINIDRIVER
if ZY1000
DRIVERFILES += zy1000/zy1000.c
JTAG_MINIDRIVER_DIR = $(srcdir)/zy1000
JTAG_SRCS += %D%/zy1000/zy1000.c
JTAG_MINIDRIVER_DIR = %D%/zy1000
endif
if MINIDRIVER_DUMMY
DRIVERFILES += minidummy/minidummy.c commands.c
JTAG_MINIDRIVER_DIR = $(srcdir)/minidummy
JTAG_SRCS += %D%/minidummy/minidummy.c %D%/commands.c
JTAG_MINIDRIVER_DIR = %D%/minidummy
endif
MINIDRIVER_IMP_DIR = $(srcdir)/minidriver
MINIDRIVER_IMP_DIR = %D%/minidriver
jtag_minidriver.h: $(JTAG_MINIDRIVER_DIR)/jtag_minidriver.h
%D%/jtag_minidriver.h: $(JTAG_MINIDRIVER_DIR)/jtag_minidriver.h
cp $< $@
BUILT_SOURCES += jtag_minidriver.h
BUILT_SOURCES += %D%/jtag_minidriver.h
CLEANFILES += jtag_minidriver.h
CLEANFILES += %D%/jtag_minidriver.h
else
MINIDRIVER_IMP_DIR = $(srcdir)/drivers
DRIVERFILES += commands.c
MINIDRIVER_IMP_DIR = %D%/drivers
JTAG_SRCS += %D%/commands.c
if HLADAPTER
SUBDIRS += hla
libjtag_la_LIBADD += $(top_builddir)/src/jtag/hla/libocdhla.la
include %D%/hla/Makefile.am
%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/hla/libocdhla.la
endif
if AICE
SUBDIRS += aice
libjtag_la_LIBADD += $(top_builddir)/src/jtag/aice/libocdaice.la
include %D%/aice/Makefile.am
%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/aice/libocdaice.la
endif
SUBDIRS += drivers
libjtag_la_LIBADD += $(top_builddir)/src/jtag/drivers/libocdjtagdrivers.la
include %D%/drivers/Makefile.am
%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/drivers/libocdjtagdrivers.la
endif
# endif // MINIDRIVER
minidriver_imp.h: $(MINIDRIVER_IMP_DIR)/minidriver_imp.h
%D%/minidriver_imp.h: $(MINIDRIVER_IMP_DIR)/minidriver_imp.h
cp $< $@
libjtag_la_SOURCES = \
adapter.c \
core.c \
interface.c \
interfaces.c \
tcl.c \
$(DRIVERFILES)
%C%_libjtag_la_SOURCES = \
%D%/adapter.c \
%D%/core.c \
%D%/interface.c \
%D%/interfaces.c \
%D%/tcl.c \
%D%/commands.h \
%D%/driver.h \
%D%/interface.h \
%D%/interfaces.h \
%D%/minidriver.h \
%D%/jtag.h \
%D%/minidriver/minidriver_imp.h \
%D%/minidummy/jtag_minidriver.h \
%D%/swd.h \
%D%/tcl.h \
$(JTAG_SRCS)
noinst_HEADERS = \
commands.h \
driver.h \
interface.h \
interfaces.h \
minidriver.h \
jtag.h \
minidriver/minidriver_imp.h \
minidummy/jtag_minidriver.h \
swd.h \
tcl.h
EXTRA_DIST = startup.tcl
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
STARTUP_TCL_SRCS += %D%/startup.tcl
+13 -26
View File
@@ -1,27 +1,14 @@
include $(top_srcdir)/common.mk
noinst_LTLIBRARIES += %D%/libocdaice.la
AM_CPPFLAGS += -I$(top_srcdir)/src/jtag/drivers $(LIBUSB1_CFLAGS) $(LIBUSB0_CFLAGS)
noinst_LTLIBRARIES = libocdaice.la
libocdaice_la_SOURCES = \
$(AICEFILES)
AICEFILES =
if AICE
AICEFILES += aice_transport.c
AICEFILES += aice_interface.c
AICEFILES += aice_port.c
AICEFILES += aice_usb.c
AICEFILES += aice_pipe.c
endif
noinst_HEADERS = \
aice_transport.h \
aice_interface.h \
aice_port.h \
aice_usb.h \
aice_pipe.h
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
%C%_libocdaice_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) $(LIBUSB0_CFLAGS)
%C%_libocdaice_la_SOURCES = \
%D%/aice_transport.c \
%D%/aice_interface.c \
%D%/aice_port.c \
%D%/aice_usb.c \
%D%/aice_pipe.c \
%D%/aice_transport.h \
%D%/aice_interface.h \
%D%/aice_port.h \
%D%/aice_usb.h \
%D%/aice_pipe.h
+2 -2
View File
@@ -786,8 +786,8 @@ static int aice_pipe_memory_mode(uint32_t coreid, enum nds_memory_select mem_sel
return ERROR_FAIL;
}
static int aice_pipe_read_tlb(uint32_t coreid, uint32_t virtual_address,
uint32_t *physical_address)
static int aice_pipe_read_tlb(uint32_t coreid, target_addr_t virtual_address,
target_addr_t *physical_address)
{
char line[AICE_PIPE_MAXLINE];
char command[AICE_PIPE_MAXLINE];
+1 -1
View File
@@ -180,7 +180,7 @@ struct aice_port_api_s {
int (*memory_mode)(uint32_t coreid, enum nds_memory_select mem_select);
/** */
int (*read_tlb)(uint32_t coreid, uint32_t virtual_address, uint32_t *physical_address);
int (*read_tlb)(uint32_t coreid, target_addr_t virtual_address, target_addr_t *physical_address);
/** */
int (*cache_ctl)(uint32_t coreid, uint32_t subtype, uint32_t address);
+10 -4
View File
@@ -2135,10 +2135,16 @@ static int aice_usb_open(struct aice_port_param_s *param)
/* usb_set_configuration required under win32 */
jtag_libusb_set_configuration(devh, 0);
jtag_libusb_claim_interface(devh, 0);
unsigned int aice_read_ep;
unsigned int aice_write_ep;
jtag_libusb_choose_interface(devh, &aice_read_ep, &aice_write_ep, -1, -1, -1);
#ifdef HAVE_LIBUSB1
jtag_libusb_choose_interface(devh, &aice_read_ep, &aice_write_ep, -1, -1, -1, LIBUSB_TRANSFER_TYPE_BULK);
#else
jtag_libusb_choose_interface(devh, &aice_read_ep, &aice_write_ep, -1, -1, -1, USB_ENDPOINT_TYPE_BULK);
#endif
LOG_DEBUG("aice_read_ep=0x%x, aice_write_ep=0x%x", aice_read_ep, aice_write_ep);
aice_handler.usb_read_ep = aice_read_ep;
aice_handler.usb_write_ep = aice_write_ep;
@@ -3424,10 +3430,10 @@ static int aice_usb_memory_mode(uint32_t coreid, enum nds_memory_select mem_sele
return ERROR_OK;
}
static int aice_usb_read_tlb(uint32_t coreid, uint32_t virtual_address,
uint32_t *physical_address)
static int aice_usb_read_tlb(uint32_t coreid, target_addr_t virtual_address,
target_addr_t *physical_address)
{
LOG_DEBUG("aice_usb_read_tlb, virtual address: 0x%08" PRIx32, virtual_address);
LOG_DEBUG("aice_usb_read_tlb, virtual address: 0x%08" TARGET_PRIxADDR, virtual_address);
uint32_t instructions[4];
uint32_t probe_result;
+2 -2
View File
@@ -1831,11 +1831,11 @@ void jtag_set_reset_config(enum reset_types type)
int jtag_get_trst(void)
{
return jtag_trst;
return jtag_trst == 1;
}
int jtag_get_srst(void)
{
return jtag_srst;
return jtag_srst == 1;
}
void jtag_set_nsrst_delay(unsigned delay)
+106 -100
View File
@@ -1,173 +1,179 @@
include $(top_srcdir)/common.mk
noinst_LTLIBRARIES += %D%/libocdjtagdrivers.la
%C%_libocdjtagdrivers_la_LIBADD =
noinst_LTLIBRARIES = libocdjtagdrivers.la
libocdjtagdrivers_la_LIBADD =
%C%_libocdjtagdrivers_la_SOURCES = \
$(DRIVERFILES) \
$(DRIVERHEADERS)
libocdjtagdrivers_la_SOURCES = \
$(DRIVERFILES)
%C%_libocdjtagdrivers_la_CPPFLAGS = $(AM_CPPFLAGS)
libocdjtagdrivers_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) \
$(LIBUSB0_CFLAGS) $(HIDAPI_CFLAGS) $(LIBFTDI_CFLAGS)
ULINK_FIRMWARE = %D%/OpenULINK
ULINK_FIRMWARE = $(srcdir)/OpenULINK
EXTRA_DIST = $(ULINK_FIRMWARE) \
usb_blaster/README.CheapClone \
Makefile.rlink \
rlink_call.m4 \
rlink_init.m4
EXTRA_DIST += $(ULINK_FIRMWARE) \
%D%/usb_blaster/README.CheapClone \
%D%/Makefile.rlink \
%D%/rlink_call.m4 \
%D%/rlink_init.m4
DRIVERFILES =
SUBDIRS=
if JLINK
if INTERNAL_LIBJAYLINK
SUBDIRS += libjaylink
libjaylink_internal_la_SOURCES = jlink.c
libjaylink_internal_la_LIBADD = libjaylink/libjaylink/libjaylink.la
libjaylink_internal_la_CPPFLAGS = -I$(builddir)/libjaylink/libjaylink \
-I$(srcdir)/libjaylink $(AM_CPPFLAGS)
noinst_LTLIBRARIES += libjaylink_internal.la
libocdjtagdrivers_la_LIBADD += libjaylink_internal.la
else
DRIVERFILES += jlink.c
endif
endif
# Standard Driver: common files
DRIVERFILES += driver.c
DRIVERFILES += %D%/driver.c
if USE_LIBUSB1
DRIVERFILES += libusb1_common.c
DRIVERFILES += %D%/libusb1_common.c
%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBUSB1_CFLAGS)
%C%_libocdjtagdrivers_la_LIBADD += $(LIBUSB1_LIBS)
endif
if USE_LIBUSB0
DRIVERFILES += usb_common.c
DRIVERFILES += %D%/usb_common.c
%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBUSB0_CFLAGS)
%C%_libocdjtagdrivers_la_LIBADD += $(LIBUSB0_LIBS)
if !USE_LIBUSB1
DRIVERFILES += libusb0_common.c
DRIVERFILES += %D%/libusb0_common.c
endif
endif
if USE_LIBFTDI
%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBFTDI_CFLAGS)
%C%_libocdjtagdrivers_la_LIBADD += $(LIBFTDI_LIBS)
endif
if USE_HIDAPI
%C%_libocdjtagdrivers_la_CPPFLAGS += $(HIDAPI_CFLAGS)
%C%_libocdjtagdrivers_la_LIBADD += $(HIDAPI_LIBS)
endif
if USE_LIBJAYLINK
%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBJAYLINK_CFLAGS)
%C%_libocdjtagdrivers_la_LIBADD += $(LIBJAYLINK_LIBS)
endif
if JLINK
DRIVERFILES += %D%/jlink.c
if INTERNAL_LIBJAYLINK
SUBDIRS += %D%/libjaylink
DIST_SUBDIRS += %D%/libjaylink
%C%_libocdjtagdrivers_la_LIBADD += %D%/libjaylink/libjaylink/libjaylink.la
%C%_libocdjtagdrivers_la_CPPFLAGS += -I$(builddir)/%D%/libjaylink/libjaylink -I$(srcdir)/%D%/libjaylink
endif
endif
if BITBANG
DRIVERFILES += bitbang.c
DRIVERFILES += %D%/bitbang.c
endif
if PARPORT
DRIVERFILES += parport.c
DRIVERFILES += %D%/parport.c
endif
if DUMMY
DRIVERFILES += dummy.c
endif
if FT2232_DRIVER
DRIVERFILES += ft2232.c
DRIVERFILES += %D%/dummy.c
endif
if FTDI
DRIVERFILES += ftdi.c mpsse.c
DRIVERFILES += %D%/ftdi.c %D%/mpsse.c
endif
if JTAG_VPI
DRIVERFILES += jtag_vpi.c
DRIVERFILES += %D%/jtag_vpi.c
endif
if USB_BLASTER_DRIVER
SUBDIRS += usb_blaster
libocdjtagdrivers_la_LIBADD += $(top_builddir)/src/jtag/drivers/usb_blaster/libocdusbblaster.la
%C%_libocdjtagdrivers_la_LIBADD += %D%/usb_blaster/libocdusbblaster.la
include %D%/usb_blaster/Makefile.am
endif
if AMTJTAGACCEL
DRIVERFILES += amt_jtagaccel.c
DRIVERFILES += %D%/amt_jtagaccel.c
endif
if EP93XX
DRIVERFILES += ep93xx.c
DRIVERFILES += %D%/ep93xx.c
endif
if AT91RM9200
DRIVERFILES += at91rm9200.c
DRIVERFILES += %D%/at91rm9200.c
endif
if GW16012
DRIVERFILES += gw16012.c
DRIVERFILES += %D%/gw16012.c
endif
if BITQ
DRIVERFILES += bitq.c
DRIVERFILES += %D%/bitq.c
endif
if PRESTO_DRIVER
DRIVERFILES += presto.c
if PRESTO
DRIVERFILES += %D%/presto.c
endif
if USBPROG
DRIVERFILES += usbprog.c
DRIVERFILES += %D%/usbprog.c
endif
if RLINK
DRIVERFILES += rlink.c rlink_speed_table.c
DRIVERFILES += %D%/rlink.c %D%/rlink_speed_table.c
endif
if ULINK
DRIVERFILES += ulink.c
DRIVERFILES += %D%/ulink.c
ulinkdir = $(pkgdatadir)/OpenULINK
dist_ulink_DATA = $(ULINK_FIRMWARE)/ulink_firmware.hex
%C%_libocdjtagdrivers_la_LIBADD += -lm
endif
if VSLLINK
DRIVERFILES += versaloon/usbtoxxx/usbtogpio.c
DRIVERFILES += versaloon/usbtoxxx/usbtojtagraw.c
DRIVERFILES += versaloon/usbtoxxx/usbtoswd.c
DRIVERFILES += versaloon/usbtoxxx/usbtopwr.c
DRIVERFILES += versaloon/usbtoxxx/usbtoxxx.c
DRIVERFILES += versaloon/versaloon.c
DRIVERFILES += vsllink.c
DRIVERFILES += %D%/versaloon/usbtoxxx/usbtogpio.c
DRIVERFILES += %D%/versaloon/usbtoxxx/usbtojtagraw.c
DRIVERFILES += %D%/versaloon/usbtoxxx/usbtoswd.c
DRIVERFILES += %D%/versaloon/usbtoxxx/usbtopwr.c
DRIVERFILES += %D%/versaloon/usbtoxxx/usbtoxxx.c
DRIVERFILES += %D%/versaloon/versaloon.c
DRIVERFILES += %D%/vsllink.c
endif
if ARMJTAGEW
DRIVERFILES += arm-jtag-ew.c
DRIVERFILES += %D%/arm-jtag-ew.c
endif
if BUSPIRATE
DRIVERFILES += buspirate.c
DRIVERFILES += %D%/buspirate.c
endif
if REMOTE_BITBANG
DRIVERFILES += remote_bitbang.c
DRIVERFILES += %D%/remote_bitbang.c
endif
if HLADAPTER
DRIVERFILES += stlink_usb.c
DRIVERFILES += ti_icdi_usb.c
DRIVERFILES += %D%/stlink_usb.c
DRIVERFILES += %D%/ti_icdi_usb.c
endif
if OSBDM
DRIVERFILES += osbdm.c
DRIVERFILES += %D%/osbdm.c
endif
if OPENDOUS
DRIVERFILES += opendous.c
DRIVERFILES += %D%/opendous.c
endif
if SYSFSGPIO
DRIVERFILES += sysfsgpio.c
DRIVERFILES += %D%/sysfsgpio.c
endif
if BCM2835GPIO
DRIVERFILES += bcm2835gpio.c
DRIVERFILES += %D%/bcm2835gpio.c
endif
if OPENJTAG
DRIVERFILES += openjtag.c
DRIVERFILES += %D%/openjtag.c
endif
if CMSIS_DAP
DRIVERFILES += cmsis_dap_usb.c
DRIVERFILES += %D%/cmsis_dap_usb.c
endif
if IMX_GPIO
DRIVERFILES += %D%/imx_gpio.c
endif
noinst_HEADERS = \
bitbang.h \
bitq.h \
ftd2xx_common.h \
libusb0_common.h \
libusb1_common.h \
libusb_common.h \
minidriver_imp.h \
mpsse.h \
rlink.h \
rlink_dtc_cmd.h \
rlink_ep1_cmd.h \
rlink_st7.h \
usb_common.h \
versaloon/usbtoxxx/usbtoxxx.h \
versaloon/usbtoxxx/usbtoxxx_internal.h \
versaloon/versaloon.h \
versaloon/versaloon_include.h \
versaloon/versaloon_internal.h
DIST_SUBDIRS = usb_blaster
if INTERNAL_LIBJAYLINK
DIST_SUBDIRS += libjaylink
if KITPROG
DRIVERFILES += %D%/kitprog.c
endif
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
DRIVERHEADERS = \
%D%/bitbang.h \
%D%/bitq.h \
%D%/libusb0_common.h \
%D%/libusb1_common.h \
%D%/libusb_common.h \
%D%/minidriver_imp.h \
%D%/mpsse.h \
%D%/rlink.h \
%D%/rlink_dtc_cmd.h \
%D%/rlink_ep1_cmd.h \
%D%/rlink_st7.h \
%D%/usb_common.h \
%D%/versaloon/usbtoxxx/usbtoxxx.h \
%D%/versaloon/usbtoxxx/usbtoxxx_internal.h \
%D%/versaloon/versaloon.h \
%D%/versaloon/versaloon_include.h \
%D%/versaloon/versaloon_internal.h
+2 -2
View File
@@ -468,8 +468,8 @@ static int bcm2835gpio_init(void)
return ERROR_JTAG_INIT_FAILED;
}
/* set 16mA drive strength */
pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000018 + 7;
/* set 4mA drive strength, slew rate limited, hysteresis on */
pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;
tdo_gpio_mode = MODE_GPIO(tdo_gpio);
tdi_gpio_mode = MODE_GPIO(tdi_gpio);
+37 -15
View File
@@ -118,6 +118,13 @@ static bool swd_mode;
* Bit 7: nRESET
*/
#define SWJ_PIN_TCK (1<<0)
#define SWJ_PIN_TMS (1<<1)
#define SWJ_PIN_TDI (1<<2)
#define SWJ_PIN_TDO (1<<3)
#define SWJ_PIN_TRST (1<<5)
#define SWJ_PIN_SRST (1<<7)
/* CMSIS-DAP SWD Commands */
#define CMD_DAP_SWD_CONFIGURE 0x13
@@ -309,9 +316,11 @@ static int cmsis_dap_usb_open(void)
int packet_size = PACKET_SIZE;
/* atmel cmsis-dap uses 512 byte reports */
/* except when it doesn't e.g. with mEDBG on SAMD10 Xplained
* board */
/* TODO: HID report descriptor should be parsed instead of
* hardcoding a match by VID */
if (target_vid == 0x03eb)
if (target_vid == 0x03eb && target_pid != 0x2145)
packet_size = 512 + 1;
cmsis_dap_handle->packet_buffer = malloc(packet_size);
@@ -764,12 +773,12 @@ static int cmsis_dap_get_status(void)
if (retval == ERROR_OK) {
LOG_INFO("SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d",
(d & (0x01 << 0)) ? 1 : 0, /* Bit 0: SWCLK/TCK */
(d & (0x01 << 1)) ? 1 : 0, /* Bit 1: SWDIO/TMS */
(d & (0x01 << 2)) ? 1 : 0, /* Bit 2: TDI */
(d & (0x01 << 3)) ? 1 : 0, /* Bit 3: TDO */
(d & (0x01 << 5)) ? 1 : 0, /* Bit 5: nTRST */
(d & (0x01 << 7)) ? 1 : 0); /* Bit 7: nRESET */
(d & SWJ_PIN_TCK) ? 1 : 0,
(d & SWJ_PIN_TMS) ? 1 : 0,
(d & SWJ_PIN_TDI) ? 1 : 0,
(d & SWJ_PIN_TDO) ? 1 : 0,
(d & SWJ_PIN_TRST) ? 1 : 0,
(d & SWJ_PIN_SRST) ? 1 : 0);
}
return retval;
@@ -812,7 +821,13 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)
return ERROR_FAIL;
}
return cmsis_dap_cmd_DAP_SWJ_Sequence(s_len, s);
retval = cmsis_dap_cmd_DAP_SWJ_Sequence(s_len, s);
if (retval != ERROR_OK)
return retval;
/* Atmel EDBG needs renew clock setting after SWJ_Sequence
* otherwise default frequency is used */
return cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz());
}
static int cmsis_dap_swd_open(void)
@@ -990,8 +1005,17 @@ static int cmsis_dap_quit(void)
static void cmsis_dap_execute_reset(struct jtag_command *cmd)
{
int retval = cmsis_dap_cmd_DAP_SWJ_Pins(cmd->cmd.reset->srst ? 0 : (1 << 7), \
(1 << 7), 0, NULL);
/* Set both TRST and SRST even if they're not enabled as
* there's no way to tristate them */
uint8_t pins = 0;
if (!cmd->cmd.reset->srst)
pins |= SWJ_PIN_SRST;
if (!cmd->cmd.reset->trst)
pins |= SWJ_PIN_TRST;
int retval = cmsis_dap_cmd_DAP_SWJ_Pins(pins,
SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL);
if (retval != ERROR_OK)
LOG_ERROR("CMSIS-DAP: Interface reset failed");
}
@@ -1475,13 +1499,11 @@ static int cmsis_dap_execute_queue(void)
static int cmsis_dap_speed(int speed)
{
if (speed > DAP_MAX_CLOCK) {
LOG_INFO("reduce speed request: %dkHz to %dkHz maximum", speed, DAP_MAX_CLOCK);
speed = DAP_MAX_CLOCK;
}
if (speed > DAP_MAX_CLOCK)
LOG_INFO("High speed (adapter_khz %d) may be limited by adapter firmware.", speed);
if (speed == 0) {
LOG_INFO("RTCK not supported");
LOG_ERROR("RTCK not supported. Set nonzero adapter_khz.");
return ERROR_JTAG_NOT_IMPLEMENTED;
}
File diff suppressed because it is too large Load Diff
-55
View File
@@ -1,55 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 by Spencer Oliver <spen@spen-soft.co.uk> *
* *
* Written by Arnim Laeuger, 2008 (from urjtag) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef OPENOCD_JTAG_DRIVERS_FTD2XX_COMMON_H
#define OPENOCD_JTAG_DRIVERS_FTD2XX_COMMON_H
#if ((BUILD_FT2232_FTD2XX == 1) || (BUILD_PRESTO_FTD2XX == 1) || (BUILD_USB_BLASTER_FTD2XX == 1))
#include <ftd2xx.h>
static const char *ftd2xx_status_string(FT_STATUS status)
{
switch (status) {
case FT_OK: return "OK";
case FT_INVALID_HANDLE: return "invalid handle";
case FT_DEVICE_NOT_FOUND: return "device not found";
case FT_DEVICE_NOT_OPENED: return "device not opened";
case FT_IO_ERROR: return "io error";
case FT_INSUFFICIENT_RESOURCES: return "insufficient resources";
case FT_INVALID_PARAMETER: return "invalid parameter";
case FT_INVALID_BAUD_RATE: return "invalid baud rate";
case FT_DEVICE_NOT_OPENED_FOR_ERASE: return "device not opened for erase";
case FT_DEVICE_NOT_OPENED_FOR_WRITE: return "device not opened for write";
case FT_FAILED_TO_WRITE_DEVICE: return "failed to write device";
case FT_EEPROM_READ_FAILED: return "eeprom read failed";
case FT_EEPROM_WRITE_FAILED: return "eeprom write failed";
case FT_EEPROM_ERASE_FAILED: return "eeprom erase failed";
case FT_EEPROM_NOT_PRESENT: return "eeprom not present";
case FT_EEPROM_NOT_PROGRAMMED: return "eeprom not programmed";
case FT_INVALID_ARGS: return "invalid args";
case FT_NOT_SUPPORTED: return "not supported";
case FT_OTHER_ERROR: return "other error";
}
return "undefined FTD2xx error";
}
#endif
#endif /* OPENOCD_JTAG_DRIVERS_FTD2XX_COMMON_H */
+552
View File
@@ -0,0 +1,552 @@
/***************************************************************************
* Copyright (C) 2017 by Grzegorz Kostka, kostka.grzegorz@gmail.com *
* *
* Based on bcm2835gpio.c *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <jtag/interface.h>
#include "bitbang.h"
#include <sys/mman.h>
#define IMX_GPIO_BASE 0x0209c000
#define IMX_GPIO_SIZE 0x00004000
#define IMX_GPIO_REGS_COUNT 8
static uint32_t imx_gpio_peri_base = IMX_GPIO_BASE;
struct imx_gpio_regs {
uint32_t dr;
uint32_t gdir;
uint32_t psr;
uint32_t icr1;
uint32_t icr2;
uint32_t imr;
uint32_t isr;
uint32_t edge_sel;
} __attribute__((aligned(IMX_GPIO_SIZE)));
static int dev_mem_fd;
static volatile struct imx_gpio_regs *pio_base;
/* GPIO setup functions */
static inline bool gpio_mode_get(int g)
{
return pio_base[g / 32].gdir >> (g & 0x1F) & 1;
}
static inline void gpio_mode_input_set(int g)
{
pio_base[g / 32].gdir &= ~(1u << (g & 0x1F));
}
static inline void gpio_mode_output_set(int g)
{
pio_base[g / 32].gdir |= (1u << (g & 0x1F));
}
static inline void gpio_mode_set(int g, int m)
{
(m) ? gpio_mode_output_set(g) : gpio_mode_input_set(g);
}
static inline void gpio_set(int g)
{
pio_base[g / 32].dr |= (1u << (g & 0x1F));
}
static inline void gpio_clear(int g)
{
pio_base[g / 32].dr &= ~(1u << (g & 0x1F));
}
static inline bool gpio_level(int g)
{
return pio_base[g / 32].dr >> (g & 0x1F) & 1;
}
static int imx_gpio_read(void);
static void imx_gpio_write(int tck, int tms, int tdi);
static void imx_gpio_reset(int trst, int srst);
static int imx_gpio_swdio_read(void);
static void imx_gpio_swdio_drive(bool is_output);
static int imx_gpio_init(void);
static int imx_gpio_quit(void);
static struct bitbang_interface imx_gpio_bitbang = {
.read = imx_gpio_read,
.write = imx_gpio_write,
.reset = imx_gpio_reset,
.swdio_read = imx_gpio_swdio_read,
.swdio_drive = imx_gpio_swdio_drive,
.blink = NULL
};
/* GPIO numbers for each signal. Negative values are invalid */
static int tck_gpio = -1;
static int tck_gpio_mode;
static int tms_gpio = -1;
static int tms_gpio_mode;
static int tdi_gpio = -1;
static int tdi_gpio_mode;
static int tdo_gpio = -1;
static int tdo_gpio_mode;
static int trst_gpio = -1;
static int trst_gpio_mode;
static int srst_gpio = -1;
static int srst_gpio_mode;
static int swclk_gpio = -1;
static int swclk_gpio_mode;
static int swdio_gpio = -1;
static int swdio_gpio_mode;
/* Transition delay coefficients. Tuned for IMX6UL 528MHz. Adjusted
* experimentally for:10kHz, 100Khz, 500KHz. Speeds above 800Khz are impossible
* to reach via memory mapped method (at least for IMX6UL@528MHz).
* Measured mmap raw GPIO toggling speed on IMX6UL@528MHz: 1.3MHz.
*/
static int speed_coeff = 50000;
static int speed_offset = 100;
static unsigned int jtag_delay;
static int imx_gpio_read(void)
{
return gpio_level(tdo_gpio);
}
static void imx_gpio_write(int tck, int tms, int tdi)
{
tms ? gpio_set(tms_gpio) : gpio_clear(tms_gpio);
tdi ? gpio_set(tdi_gpio) : gpio_clear(tdi_gpio);
tck ? gpio_set(tck_gpio) : gpio_clear(tck_gpio);
for (unsigned int i = 0; i < jtag_delay; i++)
asm volatile ("");
}
static void imx_gpio_swd_write(int tck, int tms, int tdi)
{
tdi ? gpio_set(swdio_gpio) : gpio_clear(swdio_gpio);
tck ? gpio_set(swclk_gpio) : gpio_clear(swclk_gpio);
for (unsigned int i = 0; i < jtag_delay; i++)
asm volatile ("");
}
/* (1) assert or (0) deassert reset lines */
static void imx_gpio_reset(int trst, int srst)
{
if (trst_gpio != -1)
trst ? gpio_set(trst_gpio) : gpio_clear(trst_gpio);
if (srst_gpio != -1)
srst ? gpio_set(srst_gpio) : gpio_clear(srst_gpio);
}
static void imx_gpio_swdio_drive(bool is_output)
{
if (is_output)
gpio_mode_output_set(swdio_gpio);
else
gpio_mode_input_set(swdio_gpio);
}
static int imx_gpio_swdio_read(void)
{
return gpio_level(swdio_gpio);
}
static int imx_gpio_khz(int khz, int *jtag_speed)
{
if (!khz) {
LOG_DEBUG("RCLK not supported");
return ERROR_FAIL;
}
*jtag_speed = speed_coeff/khz - speed_offset;
if (*jtag_speed < 0)
*jtag_speed = 0;
return ERROR_OK;
}
static int imx_gpio_speed_div(int speed, int *khz)
{
*khz = speed_coeff/(speed + speed_offset);
return ERROR_OK;
}
static int imx_gpio_speed(int speed)
{
jtag_delay = speed;
return ERROR_OK;
}
static int is_gpio_valid(int gpio)
{
return gpio >= 0 && gpio < 32 * IMX_GPIO_REGS_COUNT;
}
COMMAND_HANDLER(imx_gpio_handle_jtag_gpionums)
{
if (CMD_ARGC == 4) {
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);
} else if (CMD_ARGC != 0) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
command_print(CMD_CTX,
"imx_gpio GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d",
tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_tck)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
command_print(CMD_CTX, "imx_gpio GPIO config: tck = %d", tck_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_tms)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);
command_print(CMD_CTX, "imx_gpio GPIO config: tms = %d", tms_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_tdo)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);
command_print(CMD_CTX, "imx_gpio GPIO config: tdo = %d", tdo_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_tdi)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);
command_print(CMD_CTX, "imx_gpio GPIO config: tdi = %d", tdi_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_srst)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);
command_print(CMD_CTX, "imx_gpio GPIO config: srst = %d", srst_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_trst)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);
command_print(CMD_CTX, "imx_gpio GPIO config: trst = %d", trst_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_swd_gpionums)
{
if (CMD_ARGC == 2) {
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio);
} else if (CMD_ARGC != 0) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
command_print(CMD_CTX,
"imx_gpio GPIO nums: swclk = %d, swdio = %d",
swclk_gpio, swdio_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_swd_gpionum_swclk)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
command_print(CMD_CTX, "imx_gpio num: swclk = %d", swclk_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_swd_gpionum_swdio)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio);
command_print(CMD_CTX, "imx_gpio num: swdio = %d", swdio_gpio);
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_speed_coeffs)
{
if (CMD_ARGC == 2) {
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], speed_coeff);
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], speed_offset);
}
return ERROR_OK;
}
COMMAND_HANDLER(imx_gpio_handle_peripheral_base)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], imx_gpio_peri_base);
return ERROR_OK;
}
static const struct command_registration imx_gpio_command_handlers[] = {
{
.name = "imx_gpio_jtag_nums",
.handler = &imx_gpio_handle_jtag_gpionums,
.mode = COMMAND_CONFIG,
.help = "gpio numbers for tck, tms, tdi, tdo. (in that order)",
.usage = "(tck tms tdi tdo)* ",
},
{
.name = "imx_gpio_tck_num",
.handler = &imx_gpio_handle_jtag_gpionum_tck,
.mode = COMMAND_CONFIG,
.help = "gpio number for tck.",
},
{
.name = "imx_gpio_tms_num",
.handler = &imx_gpio_handle_jtag_gpionum_tms,
.mode = COMMAND_CONFIG,
.help = "gpio number for tms.",
},
{
.name = "imx_gpio_tdo_num",
.handler = &imx_gpio_handle_jtag_gpionum_tdo,
.mode = COMMAND_CONFIG,
.help = "gpio number for tdo.",
},
{
.name = "imx_gpio_tdi_num",
.handler = &imx_gpio_handle_jtag_gpionum_tdi,
.mode = COMMAND_CONFIG,
.help = "gpio number for tdi.",
},
{
.name = "imx_gpio_swd_nums",
.handler = &imx_gpio_handle_swd_gpionums,
.mode = COMMAND_CONFIG,
.help = "gpio numbers for swclk, swdio. (in that order)",
.usage = "(swclk swdio)* ",
},
{
.name = "imx_gpio_swclk_num",
.handler = &imx_gpio_handle_swd_gpionum_swclk,
.mode = COMMAND_CONFIG,
.help = "gpio number for swclk.",
},
{
.name = "imx_gpio_swdio_num",
.handler = &imx_gpio_handle_swd_gpionum_swdio,
.mode = COMMAND_CONFIG,
.help = "gpio number for swdio.",
},
{
.name = "imx_gpio_srst_num",
.handler = &imx_gpio_handle_jtag_gpionum_srst,
.mode = COMMAND_CONFIG,
.help = "gpio number for srst.",
},
{
.name = "imx_gpio_trst_num",
.handler = &imx_gpio_handle_jtag_gpionum_trst,
.mode = COMMAND_CONFIG,
.help = "gpio number for trst.",
},
{
.name = "imx_gpio_speed_coeffs",
.handler = &imx_gpio_handle_speed_coeffs,
.mode = COMMAND_CONFIG,
.help = "SPEED_COEFF and SPEED_OFFSET for delay calculations.",
},
{
.name = "imx_gpio_peripheral_base",
.handler = &imx_gpio_handle_peripheral_base,
.mode = COMMAND_CONFIG,
.help = "peripheral base to access GPIOs (0x0209c000 for most IMX).",
},
COMMAND_REGISTRATION_DONE
};
static const char * const imx_gpio_transports[] = { "jtag", "swd", NULL };
struct jtag_interface imx_gpio_interface = {
.name = "imx_gpio",
.supported = DEBUG_CAP_TMS_SEQ,
.execute_queue = bitbang_execute_queue,
.transports = imx_gpio_transports,
.swd = &bitbang_swd,
.speed = imx_gpio_speed,
.khz = imx_gpio_khz,
.speed_div = imx_gpio_speed_div,
.commands = imx_gpio_command_handlers,
.init = imx_gpio_init,
.quit = imx_gpio_quit,
};
static bool imx_gpio_jtag_mode_possible(void)
{
if (!is_gpio_valid(tck_gpio))
return 0;
if (!is_gpio_valid(tms_gpio))
return 0;
if (!is_gpio_valid(tdi_gpio))
return 0;
if (!is_gpio_valid(tdo_gpio))
return 0;
return 1;
}
static bool imx_gpio_swd_mode_possible(void)
{
if (!is_gpio_valid(swclk_gpio))
return 0;
if (!is_gpio_valid(swdio_gpio))
return 0;
return 1;
}
static int imx_gpio_init(void)
{
bitbang_interface = &imx_gpio_bitbang;
LOG_INFO("imx_gpio GPIO JTAG/SWD bitbang driver");
if (imx_gpio_jtag_mode_possible()) {
if (imx_gpio_swd_mode_possible())
LOG_INFO("JTAG and SWD modes enabled");
else
LOG_INFO("JTAG only mode enabled (specify swclk and swdio gpio to add SWD mode)");
} else if (imx_gpio_swd_mode_possible()) {
LOG_INFO("SWD only mode enabled (specify tck, tms, tdi and tdo gpios to add JTAG mode)");
} else {
LOG_ERROR("Require tck, tms, tdi and tdo gpios for JTAG mode and/or swclk and swdio gpio for SWD mode");
return ERROR_JTAG_INIT_FAILED;
}
dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (dev_mem_fd < 0) {
perror("open");
return ERROR_JTAG_INIT_FAILED;
}
LOG_INFO("imx_gpio mmap: pagesize: %u, regionsize: %u",
sysconf(_SC_PAGE_SIZE), IMX_GPIO_REGS_COUNT * IMX_GPIO_SIZE);
pio_base = mmap(NULL, IMX_GPIO_REGS_COUNT * IMX_GPIO_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED, dev_mem_fd, imx_gpio_peri_base);
if (pio_base == MAP_FAILED) {
perror("mmap");
close(dev_mem_fd);
return ERROR_JTAG_INIT_FAILED;
}
/*
* Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
* as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
*/
if (imx_gpio_jtag_mode_possible()) {
tdo_gpio_mode = gpio_mode_get(tdo_gpio);
tdi_gpio_mode = gpio_mode_get(tdi_gpio);
tck_gpio_mode = gpio_mode_get(tck_gpio);
tms_gpio_mode = gpio_mode_get(tms_gpio);
gpio_clear(tdi_gpio);
gpio_clear(tck_gpio);
gpio_set(tms_gpio);
gpio_mode_input_set(tdo_gpio);
gpio_mode_output_set(tdi_gpio);
gpio_mode_output_set(tck_gpio);
gpio_mode_output_set(tms_gpio);
}
if (imx_gpio_swd_mode_possible()) {
swclk_gpio_mode = gpio_mode_get(swclk_gpio);
swdio_gpio_mode = gpio_mode_get(swdio_gpio);
gpio_clear(swdio_gpio);
gpio_clear(swclk_gpio);
gpio_mode_output_set(swclk_gpio);
gpio_mode_output_set(swdio_gpio);
}
if (trst_gpio != -1) {
trst_gpio_mode = gpio_mode_get(trst_gpio);
gpio_set(trst_gpio);
gpio_mode_output_set(trst_gpio);
}
if (srst_gpio != -1) {
srst_gpio_mode = gpio_mode_get(srst_gpio);
gpio_set(srst_gpio);
gpio_mode_output_set(srst_gpio);
}
LOG_DEBUG("saved pinmux settings: tck %d tms %d tdi %d "
"tdo %d trst %d srst %d", tck_gpio_mode, tms_gpio_mode,
tdi_gpio_mode, tdo_gpio_mode, trst_gpio_mode, srst_gpio_mode);
if (swd_mode) {
imx_gpio_bitbang.write = imx_gpio_swd_write;
bitbang_switch_to_swd();
}
return ERROR_OK;
}
static int imx_gpio_quit(void)
{
if (imx_gpio_jtag_mode_possible()) {
gpio_mode_set(tdo_gpio, tdo_gpio_mode);
gpio_mode_set(tdi_gpio, tdi_gpio_mode);
gpio_mode_set(tck_gpio, tck_gpio_mode);
gpio_mode_set(tms_gpio, tms_gpio_mode);
}
if (imx_gpio_swd_mode_possible()) {
gpio_mode_set(swclk_gpio, swclk_gpio_mode);
gpio_mode_set(swdio_gpio, swdio_gpio_mode);
}
if (trst_gpio != -1)
gpio_mode_set(trst_gpio, trst_gpio_mode);
if (srst_gpio != -1)
gpio_mode_set(srst_gpio, srst_gpio_mode);
return ERROR_OK;
}
+226 -23
View File
@@ -314,12 +314,11 @@ static int jlink_execute_queue(void)
static int jlink_speed(int speed)
{
int ret;
uint32_t freq;
uint16_t divider;
struct jaylink_speed tmp;
int max_speed;
if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_SPEEDS)) {
ret = jaylink_get_speeds(devh, &freq, &divider);
ret = jaylink_get_speeds(devh, &tmp);
if (ret != JAYLINK_OK) {
LOG_ERROR("jaylink_get_speeds() failed: %s.",
@@ -327,8 +326,8 @@ static int jlink_speed(int speed)
return ERROR_JTAG_DEVICE_ERROR;
}
freq = freq / 1000;
max_speed = freq / divider;
tmp.freq /= 1000;
max_speed = tmp.freq / tmp.div;
} else {
max_speed = JLINK_MAX_SPEED;
}
@@ -433,15 +432,16 @@ static int select_interface(void)
static int jlink_register(void)
{
int ret;
int i;
size_t i;
bool handle_found;
size_t count;
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER))
return ERROR_OK;
ret = jaylink_register(devh, &conn, connlist, NULL, NULL);
ret = jaylink_register(devh, &conn, connlist, &count);
if (ret < 0) {
if (ret != JAYLINK_OK) {
LOG_ERROR("jaylink_register() failed: %s.",
jaylink_strerror_name(ret));
return ERROR_FAIL;
@@ -449,7 +449,7 @@ static int jlink_register(void)
handle_found = false;
for (i = 0; i < ret; i++) {
for (i = 0; i < count; i++) {
if (connlist[i].handle == conn.handle) {
handle_found = true;
break;
@@ -502,6 +502,36 @@ static bool adjust_swd_buffer_size(void)
return true;
}
static int jaylink_log_handler(const struct jaylink_context *ctx,
enum jaylink_log_level level, const char *format, va_list args,
void *user_data)
{
enum log_levels tmp;
switch (level) {
case JAYLINK_LOG_LEVEL_ERROR:
tmp = LOG_LVL_ERROR;
break;
case JAYLINK_LOG_LEVEL_WARNING:
tmp = LOG_LVL_WARNING;
break;
/*
* Forward info messages to the debug output because they are more verbose
* than info messages of OpenOCD.
*/
case JAYLINK_LOG_LEVEL_INFO:
case JAYLINK_LOG_LEVEL_DEBUG:
tmp = LOG_LVL_DEBUG;
break;
default:
tmp = LOG_LVL_WARNING;
}
log_vprintf_lf(tmp, __FILE__, __LINE__, __func__, format, args);
return 0;
}
static int jlink_init(void)
{
int ret;
@@ -515,6 +545,9 @@ static int jlink_init(void)
enum jaylink_usb_address address;
size_t length;
LOG_DEBUG("Using libjaylink %s (compiled with %s).",
jaylink_version_package_get_string(), JAYLINK_VERSION_PACKAGE_STRING);
ret = jaylink_init(&jayctx);
if (ret != JAYLINK_OK) {
@@ -523,10 +556,28 @@ static int jlink_init(void)
return ERROR_JTAG_INIT_FAILED;
}
ret = jaylink_get_device_list(jayctx, &devs);
ret = jaylink_log_set_callback(jayctx, &jaylink_log_handler, NULL);
if (ret < 0) {
LOG_ERROR("jaylink_get_device_list() failed: %s.",
if (ret != JAYLINK_OK) {
LOG_ERROR("jaylink_log_set_callback() failed: %s.",
jaylink_strerror_name(ret));
jaylink_exit(jayctx);
return ERROR_JTAG_INIT_FAILED;
}
ret = jaylink_discovery_scan(jayctx, 0);
if (ret != JAYLINK_OK) {
LOG_ERROR("jaylink_discovery_scan() failed: %s.",
jaylink_strerror_name(ret));
jaylink_exit(jayctx);
return ERROR_JTAG_INIT_FAILED;
}
ret = jaylink_get_devices(jayctx, &devs, NULL);
if (ret != JAYLINK_OK) {
LOG_ERROR("jaylink_get_devices() failed: %s.",
jaylink_strerror_name(ret));
jaylink_exit(jayctx);
return ERROR_JTAG_INIT_FAILED;
@@ -576,7 +627,7 @@ static int jlink_init(void)
LOG_ERROR("Failed to open device: %s.", jaylink_strerror_name(ret));
}
jaylink_free_device_list(devs, 1);
jaylink_free_devices(devs, true);
if (!found_device) {
LOG_ERROR("No J-Link device found.");
@@ -626,7 +677,7 @@ static int jlink_init(void)
}
}
jtag_command_version = JAYLINK_JTAG_V2;
jtag_command_version = JAYLINK_JTAG_VERSION_2;
if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_HW_VERSION)) {
ret = jaylink_get_hardware_version(devh, &hwver);
@@ -642,7 +693,7 @@ static int jlink_init(void)
LOG_INFO("Hardware version: %u.%02u", hwver.major, hwver.minor);
if (hwver.major >= 5)
jtag_command_version = JAYLINK_JTAG_V3;
jtag_command_version = JAYLINK_JTAG_VERSION_3;
}
if (iface == JAYLINK_TIF_SWD) {
@@ -685,7 +736,7 @@ static int jlink_init(void)
conn.handle = 0;
conn.pid = 0;
conn.hid = 0;
strcpy(conn.hid, "0.0.0.0");
conn.iid = 0;
conn.cid = 0;
@@ -729,6 +780,7 @@ static int jlink_init(void)
static int jlink_quit(void)
{
int ret;
size_t count;
if (trace_enabled) {
ret = jaylink_swo_stop(devh);
@@ -739,9 +791,9 @@ static int jlink_quit(void)
}
if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER)) {
ret = jaylink_unregister(devh, &conn, connlist, NULL, NULL);
ret = jaylink_unregister(devh, &conn, connlist, &count);
if (ret < 0)
if (ret != JAYLINK_OK)
LOG_ERROR("jaylink_unregister() failed: %s.",
jaylink_strerror_name(ret));
}
@@ -878,14 +930,22 @@ COMMAND_HANDLER(jlink_usb_command)
COMMAND_HANDLER(jlink_serial_command)
{
int ret;
if (CMD_ARGC != 1) {
command_print(CMD_CTX, "Need exactly one argument for jlink serial.");
return ERROR_COMMAND_SYNTAX_ERROR;
}
if (sscanf(CMD_ARGV[0], "%" SCNd32, &serial_number) != 1) {
ret = jaylink_parse_serial_number(CMD_ARGV[0], &serial_number);
if (ret == JAYLINK_ERR) {
command_print(CMD_CTX, "Invalid serial number: %s.", CMD_ARGV[0]);
return ERROR_FAIL;
} else if (ret != JAYLINK_OK) {
command_print(CMD_CTX, "jaylink_parse_serial_number() failed: %s.",
jaylink_strerror_name(ret));
return ERROR_FAIL;
}
use_serial_number = true;
@@ -951,10 +1011,10 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
if (!CMD_ARGC) {
switch (jtag_command_version) {
case JAYLINK_JTAG_V2:
case JAYLINK_JTAG_VERSION_2:
version = 2;
break;
case JAYLINK_JTAG_V3:
case JAYLINK_JTAG_VERSION_3:
version = 3;
break;
default:
@@ -970,10 +1030,10 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
switch (tmp) {
case 2:
jtag_command_version = JAYLINK_JTAG_V2;
jtag_command_version = JAYLINK_JTAG_VERSION_2;
break;
case 3:
jtag_command_version = JAYLINK_JTAG_V3;
jtag_command_version = JAYLINK_JTAG_VERSION_3;
break;
default:
command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]);
@@ -1545,6 +1605,125 @@ COMMAND_HANDLER(jlink_handle_config_command)
return ERROR_OK;
}
COMMAND_HANDLER(jlink_handle_emucom_write_command)
{
int ret;
size_t tmp;
uint32_t channel;
uint32_t length;
uint8_t *buf;
size_t dummy;
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
LOG_ERROR("Device does not support EMUCOM.");
return ERROR_FAIL;
}
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);
tmp = strlen(CMD_ARGV[1]);
if (tmp % 2 != 0) {
LOG_ERROR("Data must be encoded as hexadecimal pairs.");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
buf = malloc(tmp / 2);
if (!buf) {
LOG_ERROR("Failed to allocate buffer.");
return ERROR_FAIL;
}
dummy = unhexify(buf, CMD_ARGV[1], tmp / 2);
if (dummy != (tmp / 2)) {
LOG_ERROR("Data must be encoded as hexadecimal pairs.");
free(buf);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
length = tmp / 2;
ret = jaylink_emucom_write(devh, channel, buf, &length);
free(buf);
if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
LOG_ERROR("Channel not supported by the device.");
return ERROR_FAIL;
} else if (ret != JAYLINK_OK) {
LOG_ERROR("Failed to write to channel: %s.",
jaylink_strerror_name(ret));
return ERROR_FAIL;
}
if (length != (tmp / 2))
LOG_WARNING("Only %" PRIu32 " bytes written to the channel.", length);
return ERROR_OK;
}
COMMAND_HANDLER(jlink_handle_emucom_read_command)
{
int ret;
uint32_t channel;
uint32_t length;
uint8_t *buf;
size_t tmp;
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {
LOG_ERROR("Device does not support EMUCOM.");
return ERROR_FAIL;
}
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
buf = malloc(length * 3 + 1);
if (!buf) {
LOG_ERROR("Failed to allocate buffer.");
return ERROR_FAIL;
}
ret = jaylink_emucom_read(devh, channel, buf, &length);
if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {
LOG_ERROR("Channel is not supported by the device.");
free(buf);
return ERROR_FAIL;
} else if (ret == JAYLINK_ERR_DEV_NOT_AVAILABLE) {
LOG_ERROR("Channel is not available for the requested amount of data. "
"%" PRIu32 " bytes are avilable.", length);
free(buf);
return ERROR_FAIL;
} else if (ret != JAYLINK_OK) {
LOG_ERROR("Failed to read from channel: %s.",
jaylink_strerror_name(ret));
free(buf);
return ERROR_FAIL;
}
tmp = hexify((char *)buf + length, buf, length, 2 * length + 1);
if (tmp != 2 * length) {
LOG_ERROR("Failed to convert data into hexadecimal string.");
free(buf);
return ERROR_FAIL;
}
command_print(CMD_CTX, "%s", buf + length);
free(buf);
return ERROR_OK;
}
static const struct command_registration jlink_config_subcommand_handlers[] = {
{
.name = "usb",
@@ -1590,6 +1769,24 @@ static const struct command_registration jlink_config_subcommand_handlers[] = {
COMMAND_REGISTRATION_DONE
};
static const struct command_registration jlink_emucom_subcommand_handlers[] = {
{
.name = "write",
.handler = &jlink_handle_emucom_write_command,
.mode = COMMAND_EXEC,
.help = "write to a channel",
.usage = "<channel> <data>",
},
{
.name = "read",
.handler = &jlink_handle_emucom_read_command,
.mode = COMMAND_EXEC,
.help = "read from a channel",
.usage = "<channel> <length>"
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration jlink_subcommand_handlers[] = {
{
.name = "jtag",
@@ -1639,6 +1836,12 @@ static const struct command_registration jlink_subcommand_handlers[] = {
"this will show the device configuration",
.chain = jlink_config_subcommand_handlers,
},
{
.name = "emucom",
.mode = COMMAND_EXEC,
.help = "access EMUCOM channel",
.chain = jlink_emucom_subcommand_handlers
},
COMMAND_REGISTRATION_DONE
};
+967
View File
@@ -0,0 +1,967 @@
/***************************************************************************
* Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net> *
* based on Dominic Rath's and Benedikt Sauter's usbprog.c *
* *
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
* Copyright (C) 2011 by Jean-Christophe PLAGNIOL-VIILARD *
* plagnioj@jcrosoft.com *
* *
* Copyright (C) 2015 by Marc Schink *
* openocd-dev@marcschink.de *
* *
* Copyright (C) 2015 by Paul Fertser *
* fercerpav@gmail.com *
* *
* Copyright (C) 2015-2017 by Forest Crossman *
* cyrozap@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdint.h>
#include <hidapi.h>
#include <jtag/interface.h>
#include <jtag/swd.h>
#include <jtag/commands.h>
#include "libusb_common.h"
#define VID 0x04b4
#define PID 0xf139
#define BULK_EP_IN 1
#define BULK_EP_OUT 2
#define CONTROL_TYPE_READ 0x01
#define CONTROL_TYPE_WRITE 0x02
#define CONTROL_COMMAND_PROGRAM 0x07
#define CONTROL_MODE_POLL_PROGRAMMER_STATUS 0x01
#define CONTROL_MODE_RESET_TARGET 0x04
#define CONTROL_MODE_SET_PROGRAMMER_PROTOCOL 0x40
#define CONTROL_MODE_SYNCHRONIZE_TRANSFER 0x41
#define CONTROL_MODE_ACQUIRE_SWD_TARGET 0x42
#define CONTROL_MODE_SEND_SWD_SEQUENCE 0x43
#define PROTOCOL_JTAG 0x00
#define PROTOCOL_SWD 0x01
#define DEVICE_PSOC4 0x00
#define DEVICE_PSOC3 0x01
#define DEVICE_UNKNOWN 0x02
#define DEVICE_PSOC5 0x03
#define ACQUIRE_MODE_RESET 0x00
#define ACQUIRE_MODE_POWER_CYCLE 0x01
#define SEQUENCE_LINE_RESET 0x00
#define SEQUENCE_JTAG_TO_SWD 0x01
#define PROGRAMMER_NOK_NACK 0x00
#define PROGRAMMER_OK_ACK 0x01
#define HID_TYPE_WRITE 0x00
#define HID_TYPE_READ 0x01
#define HID_TYPE_START 0x02
#define HID_COMMAND_POWER 0x80
#define HID_COMMAND_VERSION 0x81
#define HID_COMMAND_RESET 0x82
#define HID_COMMAND_CONFIGURE 0x8f
#define HID_COMMAND_BOOTLOADER 0xa0
/* 512 bytes seems to work reliably */
#define SWD_MAX_BUFFER_LENGTH 512
struct kitprog {
hid_device *hid_handle;
struct jtag_libusb_device_handle *usb_handle;
uint16_t packet_size;
uint16_t packet_index;
uint8_t *packet_buffer;
char *serial;
uint8_t hardware_version;
uint8_t minor_version;
uint8_t major_version;
uint16_t millivolts;
bool supports_jtag_to_swd;
};
struct pending_transfer_result {
uint8_t cmd;
uint32_t data;
void *buffer;
};
static char *kitprog_serial;
static bool kitprog_init_acquire_psoc;
static int pending_transfer_count, pending_queue_len;
static struct pending_transfer_result *pending_transfers;
static int queued_retval;
static struct kitprog *kitprog_handle;
static int kitprog_usb_open(void);
static void kitprog_usb_close(void);
static int kitprog_hid_command(uint8_t *command, size_t command_length,
uint8_t *data, size_t data_length);
static int kitprog_get_version(void);
static int kitprog_get_millivolts(void);
static int kitprog_get_info(void);
static int kitprog_set_protocol(uint8_t protocol);
static int kitprog_get_status(void);
static int kitprog_set_unknown(void);
static int kitprog_acquire_psoc(uint8_t psoc_type, uint8_t acquire_mode,
uint8_t max_attempts);
static int kitprog_reset_target(void);
static int kitprog_swd_sync(void);
static int kitprog_swd_seq(uint8_t seq_type);
static int kitprog_generic_acquire(void);
static int kitprog_swd_run_queue(void);
static void kitprog_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data);
static int kitprog_swd_switch_seq(enum swd_special_seq seq);
static inline int mm_to_version(uint8_t major, uint8_t minor)
{
return (major << 8) | minor;
}
static int kitprog_init(void)
{
int retval;
kitprog_handle = malloc(sizeof(struct kitprog));
if (kitprog_handle == NULL) {
LOG_ERROR("Failed to allocate memory");
return ERROR_FAIL;
}
if (kitprog_usb_open() != ERROR_OK) {
LOG_ERROR("Can't find a KitProg device! Please check device connections and permissions.");
return ERROR_JTAG_INIT_FAILED;
}
/* Get the current KitProg version and target voltage */
if (kitprog_get_info() != ERROR_OK)
return ERROR_FAIL;
/* Compatibility check */
kitprog_handle->supports_jtag_to_swd = true;
int kitprog_version = mm_to_version(kitprog_handle->major_version, kitprog_handle->minor_version);
if (kitprog_version < mm_to_version(2, 14)) {
LOG_WARNING("KitProg firmware versions below v2.14 do not support sending JTAG to SWD sequences. These sequences will be substituted with SWD line resets.");
kitprog_handle->supports_jtag_to_swd = false;
}
/* I have no idea what this does */
if (kitprog_set_unknown() != ERROR_OK)
return ERROR_FAIL;
/* SWD won't work unless we do this */
if (kitprog_swd_sync() != ERROR_OK)
return ERROR_FAIL;
/* Set the protocol to SWD */
if (kitprog_set_protocol(PROTOCOL_SWD) != ERROR_OK)
return ERROR_FAIL;
/* Reset the SWD bus */
if (kitprog_swd_seq(SEQUENCE_LINE_RESET) != ERROR_OK)
return ERROR_FAIL;
if (kitprog_init_acquire_psoc) {
/* Try to acquire any device that will respond */
retval = kitprog_generic_acquire();
if (retval != ERROR_OK) {
LOG_ERROR("No PSoC devices found");
return retval;
}
}
/* Allocate packet buffers and queues */
kitprog_handle->packet_size = SWD_MAX_BUFFER_LENGTH;
kitprog_handle->packet_buffer = malloc(SWD_MAX_BUFFER_LENGTH);
if (kitprog_handle->packet_buffer == NULL) {
LOG_ERROR("Failed to allocate memory for the packet buffer");
return ERROR_FAIL;
}
pending_queue_len = SWD_MAX_BUFFER_LENGTH / 5;
pending_transfers = malloc(pending_queue_len * sizeof(*pending_transfers));
if (pending_transfers == NULL) {
LOG_ERROR("Failed to allocate memory for the SWD transfer queue");
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_quit(void)
{
kitprog_usb_close();
if (kitprog_handle->packet_buffer != NULL)
free(kitprog_handle->packet_buffer);
if (kitprog_handle->serial != NULL)
free(kitprog_handle->serial);
if (kitprog_handle != NULL)
free(kitprog_handle);
if (kitprog_serial != NULL)
free(kitprog_serial);
if (pending_transfers != NULL)
free(pending_transfers);
return ERROR_OK;
}
/*************** kitprog usb functions *********************/
static int kitprog_get_usb_serial(void)
{
int retval;
const uint8_t str_index = 128; /* This seems to be a constant */
char desc_string[256+1]; /* Max size of string descriptor */
retval = libusb_get_string_descriptor_ascii(kitprog_handle->usb_handle,
str_index, (unsigned char *)desc_string, sizeof(desc_string)-1);
if (retval < 0) {
LOG_ERROR("libusb_get_string_descriptor_ascii() failed with %d", retval);
return ERROR_FAIL;
}
/* Null terminate descriptor string */
desc_string[retval] = '\0';
/* Allocate memory for the serial number */
kitprog_handle->serial = calloc(retval + 1, sizeof(char));
if (kitprog_handle->serial == NULL) {
LOG_ERROR("Failed to allocate memory for the serial number");
return ERROR_FAIL;
}
/* Store the serial number */
strncpy(kitprog_handle->serial, desc_string, retval + 1);
return ERROR_OK;
}
static int kitprog_usb_open(void)
{
const uint16_t vids[] = { VID, 0 };
const uint16_t pids[] = { PID, 0 };
if (jtag_libusb_open(vids, pids, kitprog_serial,
&kitprog_handle->usb_handle) != ERROR_OK) {
LOG_ERROR("Failed to open or find the device");
return ERROR_FAIL;
}
/* Get the serial number for the device */
if (kitprog_get_usb_serial() != ERROR_OK)
LOG_WARNING("Failed to get KitProg serial number");
/* Convert the ASCII serial number into a (wchar_t *) */
size_t len = strlen(kitprog_handle->serial);
wchar_t *hid_serial = calloc(len + 1, sizeof(wchar_t));
if (hid_serial == NULL) {
LOG_ERROR("Failed to allocate memory for the serial number");
return ERROR_FAIL;
}
if (mbstowcs(hid_serial, kitprog_handle->serial, len + 1) == (size_t)-1) {
free(hid_serial);
LOG_ERROR("Failed to convert serial number");
return ERROR_FAIL;
}
/* Use HID for the KitBridge interface */
kitprog_handle->hid_handle = hid_open(VID, PID, hid_serial);
free(hid_serial);
if (kitprog_handle->hid_handle == NULL) {
LOG_ERROR("Failed to open KitBridge (HID) interface");
return ERROR_FAIL;
}
/* Claim the KitProg Programmer (bulk transfer) interface */
if (jtag_libusb_claim_interface(kitprog_handle->usb_handle, 1) != ERROR_OK) {
LOG_ERROR("Failed to claim KitProg Programmer (bulk transfer) interface");
return ERROR_FAIL;
}
return ERROR_OK;
}
static void kitprog_usb_close(void)
{
if (kitprog_handle->hid_handle != NULL) {
hid_close(kitprog_handle->hid_handle);
hid_exit();
}
jtag_libusb_close(kitprog_handle->usb_handle);
}
/*************** kitprog lowlevel functions *********************/
static int kitprog_hid_command(uint8_t *command, size_t command_length,
uint8_t *data, size_t data_length)
{
int ret;
ret = hid_write(kitprog_handle->hid_handle, command, command_length);
if (ret < 0) {
LOG_DEBUG("HID write returned %i", ret);
return ERROR_FAIL;
}
ret = hid_read(kitprog_handle->hid_handle, data, data_length);
if (ret < 0) {
LOG_DEBUG("HID read returned %i", ret);
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_get_version(void)
{
int ret;
unsigned char command[3] = {HID_TYPE_START | HID_TYPE_WRITE, 0x00, HID_COMMAND_VERSION};
unsigned char data[64];
ret = kitprog_hid_command(command, sizeof command, data, sizeof data);
if (ret != ERROR_OK)
return ret;
kitprog_handle->hardware_version = data[1];
kitprog_handle->minor_version = data[2];
kitprog_handle->major_version = data[3];
return ERROR_OK;
}
static int kitprog_get_millivolts(void)
{
int ret;
unsigned char command[3] = {HID_TYPE_START | HID_TYPE_READ, 0x00, HID_COMMAND_POWER};
unsigned char data[64];
ret = kitprog_hid_command(command, sizeof command, data, sizeof data);
if (ret != ERROR_OK)
return ret;
kitprog_handle->millivolts = (data[4] << 8) | data[3];
return ERROR_OK;
}
static int kitprog_get_info(void)
{
/* Get the device version information */
if (kitprog_get_version() == ERROR_OK) {
LOG_INFO("KitProg v%u.%02u",
kitprog_handle->major_version, kitprog_handle->minor_version);
LOG_INFO("Hardware version: %u",
kitprog_handle->hardware_version);
} else {
LOG_ERROR("Failed to get KitProg version");
return ERROR_FAIL;
}
/* Get the current reported target voltage */
if (kitprog_get_millivolts() == ERROR_OK) {
LOG_INFO("VTARG = %u.%03u V",
kitprog_handle->millivolts / 1000, kitprog_handle->millivolts % 1000);
} else {
LOG_ERROR("Failed to get target voltage");
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_set_protocol(uint8_t protocol)
{
int transferred;
char status = PROGRAMMER_NOK_NACK;
transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_SET_PROGRAMMER_PROTOCOL << 8) | CONTROL_COMMAND_PROGRAM,
protocol, &status, 1, 0);
if (transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
if (status != PROGRAMMER_OK_ACK) {
LOG_DEBUG("Programmer did not respond OK");
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_get_status(void)
{
int transferred = 0;
char status = PROGRAMMER_NOK_NACK;
/* Try a maximum of three times */
for (int i = 0; (i < 3) && (transferred == 0); i++) {
transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_READ,
(CONTROL_MODE_POLL_PROGRAMMER_STATUS << 8) | CONTROL_COMMAND_PROGRAM,
0, &status, 1, 0);
jtag_sleep(1000);
}
if (transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
if (status != PROGRAMMER_OK_ACK) {
LOG_DEBUG("Programmer did not respond OK");
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_set_unknown(void)
{
int transferred;
char status = PROGRAMMER_NOK_NACK;
transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(0x03 << 8) | 0x04,
0, &status, 1, 0);
if (transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
if (status != PROGRAMMER_OK_ACK) {
LOG_DEBUG("Programmer did not respond OK");
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_acquire_psoc(uint8_t psoc_type, uint8_t acquire_mode,
uint8_t max_attempts)
{
int transferred;
char status = PROGRAMMER_NOK_NACK;
transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_ACQUIRE_SWD_TARGET << 8) | CONTROL_COMMAND_PROGRAM,
(max_attempts << 8) | (acquire_mode << 4) | psoc_type, &status, 1, 0);
if (transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
if (status != PROGRAMMER_OK_ACK) {
LOG_DEBUG("Programmer did not respond OK");
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_reset_target(void)
{
int transferred;
char status = PROGRAMMER_NOK_NACK;
transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_RESET_TARGET << 8) | CONTROL_COMMAND_PROGRAM,
0, &status, 1, 0);
if (transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
if (status != PROGRAMMER_OK_ACK) {
LOG_DEBUG("Programmer did not respond OK");
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_swd_sync(void)
{
int transferred;
char status = PROGRAMMER_NOK_NACK;
transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_SYNCHRONIZE_TRANSFER << 8) | CONTROL_COMMAND_PROGRAM,
0, &status, 1, 0);
if (transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
if (status != PROGRAMMER_OK_ACK) {
LOG_DEBUG("Programmer did not respond OK");
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_swd_seq(uint8_t seq_type)
{
int transferred;
char status = PROGRAMMER_NOK_NACK;
transferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,
CONTROL_TYPE_WRITE,
(CONTROL_MODE_SEND_SWD_SEQUENCE << 8) | CONTROL_COMMAND_PROGRAM,
seq_type, &status, 1, 0);
if (transferred == 0) {
LOG_DEBUG("Zero bytes transferred");
return ERROR_FAIL;
}
if (status != PROGRAMMER_OK_ACK) {
LOG_DEBUG("Programmer did not respond OK");
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_generic_acquire(void)
{
const uint8_t devices[] = {DEVICE_PSOC4, DEVICE_PSOC3, DEVICE_PSOC5};
int retval;
int acquire_count = 0;
/* Due to the way the SWD port is shared between the Test Controller (TC)
* and the Cortex-M3 DAP on the PSoC 5LP, the TC is the default SWD target
* after power is applied. To access the DAP, the PSoC 5LP requires at least
* one acquisition sequence to be run (which switches the SWD mux from the
* TC to the DAP). However, after the mux is switched, the Cortex-M3 will be
* held in reset until a series of registers are written to (see section 5.2
* of the PSoC 5LP Device Programming Specifications for details).
*
* Instead of writing the registers in this function, we just do what the
* Cypress tools do and run the acquisition sequence a second time. This
* will take the Cortex-M3 out of reset and enable debugging.
*/
for (int i = 0; i < 2; i++) {
for (uint8_t j = 0; j < sizeof devices && acquire_count == i; j++) {
retval = kitprog_acquire_psoc(devices[j], ACQUIRE_MODE_RESET, 3);
if (retval != ERROR_OK) {
LOG_DEBUG("Aquisition function failed for device 0x%02x.", devices[j]);
return retval;
}
if (kitprog_get_status() == ERROR_OK)
acquire_count++;
}
jtag_sleep(10);
}
if (acquire_count < 2)
return ERROR_FAIL;
return ERROR_OK;
}
/*************** swd wrapper functions *********************/
static int kitprog_swd_init(void)
{
return ERROR_OK;
}
static void kitprog_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
{
assert(!(cmd & SWD_CMD_RnW));
kitprog_swd_queue_cmd(cmd, NULL, value);
}
static void kitprog_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
{
assert(cmd & SWD_CMD_RnW);
kitprog_swd_queue_cmd(cmd, value, 0);
}
/*************** swd lowlevel functions ********************/
static int kitprog_swd_switch_seq(enum swd_special_seq seq)
{
switch (seq) {
case JTAG_TO_SWD:
if (kitprog_handle->supports_jtag_to_swd) {
LOG_DEBUG("JTAG to SWD");
if (kitprog_swd_seq(SEQUENCE_JTAG_TO_SWD) != ERROR_OK)
return ERROR_FAIL;
break;
} else {
LOG_DEBUG("JTAG to SWD not supported");
/* Fall through to fix target reset issue */
}
case LINE_RESET:
LOG_DEBUG("SWD line reset");
if (kitprog_swd_seq(SEQUENCE_LINE_RESET) != ERROR_OK)
return ERROR_FAIL;
break;
default:
LOG_ERROR("Sequence %d not supported.", seq);
return ERROR_FAIL;
}
return ERROR_OK;
}
static int kitprog_swd_run_queue(void)
{
int ret;
size_t read_count = 0;
size_t read_index = 0;
size_t write_count = 0;
uint8_t *buffer = kitprog_handle->packet_buffer;
do {
LOG_DEBUG("Executing %d queued transactions", pending_transfer_count);
if (queued_retval != ERROR_OK) {
LOG_DEBUG("Skipping due to previous errors: %d", queued_retval);
break;
}
if (!pending_transfer_count)
break;
for (int i = 0; i < pending_transfer_count; i++) {
uint8_t cmd = pending_transfers[i].cmd;
uint32_t data = pending_transfers[i].data;
/* When proper WAIT handling is implemented in the
* common SWD framework, this kludge can be
* removed. However, this might lead to minor
* performance degradation as the adapter wouldn't be
* able to automatically retry anything (because ARM
* has forgotten to implement sticky error flags
* clearing). See also comments regarding
* cmsis_dap_cmd_DAP_TFER_Configure() and
* cmsis_dap_cmd_DAP_SWD_Configure() in
* cmsis_dap_init().
*/
if (!(cmd & SWD_CMD_RnW) &&
!(cmd & SWD_CMD_APnDP) &&
(cmd & SWD_CMD_A32) >> 1 == DP_CTRL_STAT &&
(data & CORUNDETECT)) {
LOG_DEBUG("refusing to enable sticky overrun detection");
data &= ~CORUNDETECT;
}
#if 0
LOG_DEBUG("%s %s reg %x %"PRIx32,
cmd & SWD_CMD_APnDP ? "AP" : "DP",
cmd & SWD_CMD_RnW ? "read" : "write",
(cmd & SWD_CMD_A32) >> 1, data);
#endif
buffer[write_count++] = (cmd | SWD_CMD_START | SWD_CMD_PARK) & ~SWD_CMD_STOP;
read_count++;
if (!(cmd & SWD_CMD_RnW)) {
buffer[write_count++] = (data) & 0xff;
buffer[write_count++] = (data >> 8) & 0xff;
buffer[write_count++] = (data >> 16) & 0xff;
buffer[write_count++] = (data >> 24) & 0xff;
} else {
read_count += 4;
}
}
ret = jtag_libusb_bulk_write(kitprog_handle->usb_handle,
BULK_EP_OUT, (char *)buffer, write_count, 0);
if (ret > 0) {
queued_retval = ERROR_OK;
} else {
LOG_ERROR("Bulk write failed");
queued_retval = ERROR_FAIL;
break;
}
/* We use the maximum buffer size here because the KitProg sometimes
* doesn't like bulk reads of fewer than 62 bytes. (?!?!)
*/
ret = jtag_libusb_bulk_read(kitprog_handle->usb_handle,
BULK_EP_IN | LIBUSB_ENDPOINT_IN, (char *)buffer,
SWD_MAX_BUFFER_LENGTH, 0);
if (ret > 0) {
/* Handle garbage data by offsetting the initial read index */
if ((unsigned int)ret > read_count)
read_index = ret - read_count;
queued_retval = ERROR_OK;
} else {
LOG_ERROR("Bulk read failed");
queued_retval = ERROR_FAIL;
break;
}
for (int i = 0; i < pending_transfer_count; i++) {
if (pending_transfers[i].cmd & SWD_CMD_RnW) {
uint32_t data = le_to_h_u32(&buffer[read_index]);
#if 0
LOG_DEBUG("Read result: %"PRIx32, data);
#endif
if (pending_transfers[i].buffer)
*(uint32_t *)pending_transfers[i].buffer = data;
read_index += 4;
}
uint8_t ack = buffer[read_index] & 0x07;
if (ack != SWD_ACK_OK || (buffer[read_index] & 0x08)) {
LOG_DEBUG("SWD ack not OK: %d %s", i,
ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK");
queued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL;
break;
}
read_index++;
}
} while (0);
pending_transfer_count = 0;
int retval = queued_retval;
queued_retval = ERROR_OK;
return retval;
}
static void kitprog_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
{
if (pending_transfer_count == pending_queue_len) {
/* Not enough room in the queue. Run the queue. */
queued_retval = kitprog_swd_run_queue();
}
if (queued_retval != ERROR_OK)
return;
pending_transfers[pending_transfer_count].data = data;
pending_transfers[pending_transfer_count].cmd = cmd;
if (cmd & SWD_CMD_RnW) {
/* Queue a read transaction */
pending_transfers[pending_transfer_count].buffer = dst;
}
pending_transfer_count++;
}
/*************** jtag lowlevel functions ********************/
static void kitprog_execute_reset(struct jtag_command *cmd)
{
int retval = ERROR_OK;
if (cmd->cmd.reset->srst == 1) {
retval = kitprog_reset_target();
/* Since the previous command also disables SWCLK output, we need to send an
* SWD bus reset command to re-enable it. For some reason, running
* kitprog_swd_seq() immediately after kitprog_reset_target() won't
* actually fix this. Instead, kitprog_swd_seq() will be run once OpenOCD
* tries to send a JTAG-to-SWD sequence, which should happen during
* swd_check_reconnect (see the JTAG_TO_SWD case in kitprog_swd_switch_seq).
*/
}
if (retval != ERROR_OK)
LOG_ERROR("KitProg: Interface reset failed");
}
static void kitprog_execute_sleep(struct jtag_command *cmd)
{
jtag_sleep(cmd->cmd.sleep->us);
}
static void kitprog_execute_command(struct jtag_command *cmd)
{
switch (cmd->type) {
case JTAG_RESET:
kitprog_execute_reset(cmd);
break;
case JTAG_SLEEP:
kitprog_execute_sleep(cmd);
break;
default:
LOG_ERROR("BUG: unknown JTAG command type encountered");
exit(-1);
}
}
static int kitprog_execute_queue(void)
{
struct jtag_command *cmd = jtag_command_queue;
while (cmd != NULL) {
kitprog_execute_command(cmd);
cmd = cmd->next;
}
return ERROR_OK;
}
COMMAND_HANDLER(kitprog_handle_info_command)
{
int retval = kitprog_get_info();
return retval;
}
COMMAND_HANDLER(kitprog_handle_acquire_psoc_command)
{
int retval = kitprog_generic_acquire();
return retval;
}
COMMAND_HANDLER(kitprog_handle_serial_command)
{
if (CMD_ARGC == 1) {
size_t len = strlen(CMD_ARGV[0]);
kitprog_serial = calloc(len + 1, sizeof(char));
if (kitprog_serial == NULL) {
LOG_ERROR("Failed to allocate memory for the serial number");
return ERROR_FAIL;
}
strncpy(kitprog_serial, CMD_ARGV[0], len + 1);
} else {
LOG_ERROR("expected exactly one argument to kitprog_serial <serial-number>");
return ERROR_FAIL;
}
return ERROR_OK;
}
COMMAND_HANDLER(kitprog_handle_init_acquire_psoc_command)
{
kitprog_init_acquire_psoc = true;
return ERROR_OK;
}
static const struct command_registration kitprog_subcommand_handlers[] = {
{
.name = "info",
.handler = &kitprog_handle_info_command,
.mode = COMMAND_EXEC,
.usage = "",
.help = "show KitProg info",
},
{
.name = "acquire_psoc",
.handler = &kitprog_handle_acquire_psoc_command,
.mode = COMMAND_EXEC,
.usage = "",
.help = "try to acquire a PSoC",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration kitprog_command_handlers[] = {
{
.name = "kitprog",
.mode = COMMAND_ANY,
.help = "perform KitProg management",
.usage = "<cmd>",
.chain = kitprog_subcommand_handlers,
},
{
.name = "kitprog_serial",
.handler = &kitprog_handle_serial_command,
.mode = COMMAND_CONFIG,
.help = "set the serial number of the adapter",
.usage = "serial_string",
},
{
.name = "kitprog_init_acquire_psoc",
.handler = &kitprog_handle_init_acquire_psoc_command,
.mode = COMMAND_CONFIG,
.help = "try to acquire a PSoC during init",
.usage = "",
},
COMMAND_REGISTRATION_DONE
};
static const struct swd_driver kitprog_swd = {
.init = kitprog_swd_init,
.switch_seq = kitprog_swd_switch_seq,
.read_reg = kitprog_swd_read_reg,
.write_reg = kitprog_swd_write_reg,
.run = kitprog_swd_run_queue,
};
static const char * const kitprog_transports[] = { "swd", NULL };
struct jtag_interface kitprog_interface = {
.name = "kitprog",
.commands = kitprog_command_handlers,
.transports = kitprog_transports,
.swd = &kitprog_swd,
.execute_queue = kitprog_execute_queue,
.init = kitprog_init,
.quit = kitprog_quit
};
+3 -2
View File
@@ -146,7 +146,7 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
unsigned int *usb_read_ep,
unsigned int *usb_write_ep,
int bclass, int subclass, int protocol)
int bclass, int subclass, int protocol, int trans_type)
{
struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
struct usb_interface *iface = udev->config->interface;
@@ -157,7 +157,8 @@ int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
for (int i = 0; i < desc->bNumEndpoints; i++) {
if ((bclass > 0 && desc->bInterfaceClass != bclass) ||
(subclass > 0 && desc->bInterfaceSubClass != subclass) ||
(protocol > 0 && desc->bInterfaceProtocol != protocol))
(protocol > 0 && desc->bInterfaceProtocol != protocol) ||
(trans_type > 0 && (desc->endpoint[i].bmAttributes & 0x3) != trans_type))
continue;
uint8_t epnum = desc->endpoint[i].bEndpointAddress;
+1 -1
View File
@@ -67,7 +67,7 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
unsigned int *usb_read_ep,
unsigned int *usb_write_ep,
int bclass, int subclass, int protocol);
int bclass, int subclass, int protocol, int trans_type);
int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid);
#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H */
+3 -1
View File
@@ -187,7 +187,7 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
unsigned int *usb_read_ep,
unsigned int *usb_write_ep,
int bclass, int subclass, int protocol)
int bclass, int subclass, int protocol, int trans_type)
{
struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
const struct libusb_interface *inter;
@@ -210,6 +210,8 @@ int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
continue;
epdesc = &interdesc->endpoint[k];
if (trans_type > 0 && (epdesc->bmAttributes & 0x3) != trans_type)
continue;
uint8_t epnum = epdesc->bEndpointAddress;
bool is_input = epnum & 0x80;
+2 -1
View File
@@ -69,12 +69,13 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh,
* @param bclass `bInterfaceClass` to match, or -1 to ignore this field.
* @param subclass `bInterfaceSubClass` to match, or -1 to ignore this field.
* @param protocol `bInterfaceProtocol` to match, or -1 to ignore this field.
* @param trans_type `bmAttributes Bits 0..1 Transfer type` to match, or -1 to ignore this field.
* @returns Returns ERROR_OK on success, ERROR_FAIL otherwise.
*/
int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh,
unsigned int *usb_read_ep,
unsigned int *usb_write_ep,
int bclass, int subclass, int protocol);
int bclass, int subclass, int protocol, int trans_type);
int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid);
#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H */
+2 -2
View File
@@ -19,9 +19,9 @@
#define OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H
#ifdef HAVE_LIBUSB1
#include <libusb1_common.h>
#include "libusb1_common.h"
#else
#include <libusb0_common.h>
#include "libusb0_common.h"
#endif
#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H */
+22 -6
View File
@@ -247,8 +247,8 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, con
err = libusb_detach_kernel_driver(ctx->usb_dev, ctx->interface);
if (err != LIBUSB_SUCCESS && err != LIBUSB_ERROR_NOT_FOUND
&& err != LIBUSB_ERROR_NOT_SUPPORTED) {
LOG_ERROR("libusb_detach_kernel_driver() failed with %s", libusb_error_name(err));
goto error;
LOG_WARNING("libusb_detach_kernel_driver() failed with %s, trying to continue anyway",
libusb_error_name(err));
}
err = libusb_claim_interface(ctx->usb_dev, ctx->interface);
@@ -872,6 +872,8 @@ int mpsse_flush(struct mpsse_ctx *ctx)
libusb_fill_bulk_transfer(write_transfer, ctx->usb_dev, ctx->out_ep, ctx->write_buffer,
ctx->write_count, write_cb, &write_result, ctx->usb_write_timeout);
retval = libusb_submit_transfer(write_transfer);
if (retval != LIBUSB_SUCCESS)
goto error_check;
if (ctx->read_count) {
read_transfer = libusb_alloc_transfer(0);
@@ -879,22 +881,36 @@ int mpsse_flush(struct mpsse_ctx *ctx)
ctx->read_chunk_size, read_cb, &read_result,
ctx->usb_read_timeout);
retval = libusb_submit_transfer(read_transfer);
if (retval != LIBUSB_SUCCESS)
goto error_check;
}
/* Polling loop, more or less taken from libftdi */
while (!write_result.done || !read_result.done) {
retval = libusb_handle_events(ctx->usb_ctx);
struct timeval timeout_usb;
timeout_usb.tv_sec = 1;
timeout_usb.tv_usec = 0;
retval = libusb_handle_events_timeout_completed(ctx->usb_ctx, &timeout_usb, NULL);
keep_alive();
if (retval != LIBUSB_SUCCESS && retval != LIBUSB_ERROR_INTERRUPTED) {
if (retval == LIBUSB_ERROR_NO_DEVICE || retval == LIBUSB_ERROR_INTERRUPTED)
break;
if (retval != LIBUSB_SUCCESS) {
libusb_cancel_transfer(write_transfer);
if (read_transfer)
libusb_cancel_transfer(read_transfer);
while (!write_result.done || !read_result.done)
if (libusb_handle_events(ctx->usb_ctx) != LIBUSB_SUCCESS)
while (!write_result.done || !read_result.done) {
retval = libusb_handle_events_timeout_completed(ctx->usb_ctx,
&timeout_usb, NULL);
if (retval != LIBUSB_SUCCESS)
break;
}
}
}
error_check:
if (retval != LIBUSB_SUCCESS) {
LOG_ERROR("libusb_handle_events() failed with %s", libusb_error_name(retval));
retval = ERROR_FAIL;
+248 -184
View File
@@ -2,6 +2,10 @@
* Driver for OpenJTAG Project (www.openjtag.org) *
* Compatible with libftdi and ftd2xx drivers. *
* *
* Cypress CY7C65215 support *
* Copyright (C) 2015 Vianney le Clément de Saint-Marcq, Essensium NV *
* <vianney.leclement@essensium.com> *
* *
* Copyright (C) 2010 by Ivan Meleca <mileca@gmail.com> *
* *
* Copyright (C) 2013 by Ryan Corbin, GlueLogix Inc. <corbin.ryan@gmail.com> *
@@ -41,7 +45,18 @@
#include <jtag/interface.h>
#include <jtag/commands.h>
#include "usb_common.h"
#include "libusb_common.h"
static enum {
OPENJTAG_VARIANT_STANDARD,
OPENJTAG_VARIANT_CY7C65215,
} openjtag_variant = OPENJTAG_VARIANT_STANDARD;
static const char * const openjtag_variant_names[] = {
"standard",
"cy7c65215",
NULL
};
/*
* OpenJTAG-OpenOCD state conversion
@@ -66,19 +81,8 @@ typedef enum openjtag_tap_state {
OPENJTAG_TAP_UPDATE_IR = 15,
} openjtag_tap_state_t;
#if (BUILD_OPENJTAG_FTD2XX == 1 && BUILD_OPENJTAG_LIBFTDI == 1)
#error "BUILD_OPENJTAG_FTD2XX && BUILD_OPENJTAG_LIBFTDI "
"are mutually exclusive"
#elif (BUILD_OPENJTAG_FTD2XX != 1 && BUILD_OPENJTAG_LIBFTDI != 1)
#error "BUILD_OPENJTAG_FTD2XX || BUILD_OPENJTAG_LIBFTDI must be chosen"
#endif
/* OPENJTAG access library includes */
#if BUILD_OPENJTAG_FTD2XX == 1
#include <ftd2xx.h>
#elif BUILD_OPENJTAG_LIBFTDI == 1
#include <ftdi.h>
#endif
/* OpenJTAG vid/pid */
static uint16_t openjtag_vid = 0x0403;
@@ -86,12 +90,7 @@ static uint16_t openjtag_pid = 0x6001;
static char *openjtag_device_desc;
#if BUILD_OPENJTAG_FTD2XX == 1
static FT_HANDLE ftdih;
#elif BUILD_OPENJTAG_LIBFTDI == 1
static struct ftdi_context ftdic;
#endif
#define OPENJTAG_BUFFER_SIZE 504
#define OPENJTAG_MAX_PENDING_RESULTS 256
@@ -112,10 +111,24 @@ static uint8_t usb_rx_buf[OPENJTAG_BUFFER_SIZE];
static struct openjtag_scan_result openjtag_scan_result_buffer[OPENJTAG_MAX_PENDING_RESULTS];
static int openjtag_scan_result_count;
/* Openocd usb handler */
struct openocd {
struct usb_dev_handle *usb_handle;
};
static jtag_libusb_device_handle *usbh;
/* CY7C65215 model only */
#define CY7C65215_JTAG_REQUEST 0x40 /* bmRequestType: vendor host-to-device */
#define CY7C65215_JTAG_ENABLE 0xD0 /* bRequest: enable JTAG */
#define CY7C65215_JTAG_DISABLE 0xD1 /* bRequest: disable JTAG */
#define CY7C65215_JTAG_READ 0xD2 /* bRequest: read buffer */
#define CY7C65215_JTAG_WRITE 0xD3 /* bRequest: write buffer */
#define CY7C65215_USB_TIMEOUT 100
static const uint16_t cy7c65215_vids[] = {0x04b4, 0};
static const uint16_t cy7c65215_pids[] = {0x0007, 0};
#define CY7C65215_JTAG_CLASS 0xff
#define CY7C65215_JTAG_SUBCLASS 0x04
static unsigned int ep_in, ep_out;
#ifdef _DEBUG_USB_COMMS_
@@ -201,26 +214,9 @@ static int8_t openjtag_get_tap_state(int8_t state)
}
}
static int openjtag_buf_write(
static int openjtag_buf_write_standard(
uint8_t *buf, int size, uint32_t *bytes_written)
{
#if BUILD_OPENJTAG_FTD2XX == 1
FT_STATUS status;
DWORD dw_bytes_written;
#ifdef _DEBUG_USB_COMMS_
openjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);
#endif
status = FT_Write(ftdih, buf, size, &dw_bytes_written);
if (status != FT_OK) {
*bytes_written = dw_bytes_written;
LOG_ERROR("FT_Write returned: %u", status);
return ERROR_JTAG_DEVICE_ERROR;
}
*bytes_written = dw_bytes_written;
return ERROR_OK;
#elif BUILD_OPENJTAG_LIBFTDI == 1
int retval;
#ifdef _DEBUG_USB_COMMS_
openjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);
@@ -236,36 +232,56 @@ static int openjtag_buf_write(
*bytes_written += retval;
return ERROR_OK;
#endif
}
static int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
static int openjtag_buf_write_cy7c65215(
uint8_t *buf, int size, uint32_t *bytes_written)
{
#if BUILD_OPENJTAG_FTD2XX == 1
DWORD dw_bytes_read;
FT_STATUS status;
int timeout = 50;
*bytes_read = 0;
while (qty && (*bytes_read < qty) && timeout--) {
status = FT_Read(ftdih, buf + *bytes_read,
qty - *bytes_read, &dw_bytes_read);
if (status != FT_OK) {
*bytes_read = dw_bytes_read;
LOG_ERROR("FT_Read returned: %u", status);
return ERROR_JTAG_DEVICE_ERROR;
}
*bytes_read += dw_bytes_read;
}
int ret;
#ifdef _DEBUG_USB_COMMS_
openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);
openjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);
#endif
if (size == 0) {
*bytes_written = 0;
return ERROR_OK;
}
ret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,
CY7C65215_JTAG_WRITE, size, 0,
NULL, 0, CY7C65215_USB_TIMEOUT);
if (ret < 0) {
LOG_ERROR("vendor command failed, error %d", ret);
return ERROR_JTAG_DEVICE_ERROR;
}
ret = jtag_libusb_bulk_write(usbh, ep_out, (char *)buf, size,
CY7C65215_USB_TIMEOUT);
if (ret < 0) {
LOG_ERROR("bulk write failed, error %d", ret);
return ERROR_JTAG_DEVICE_ERROR;
}
*bytes_written = ret;
return ERROR_OK;
#elif BUILD_OPENJTAG_LIBFTDI == 1
}
static int openjtag_buf_write(
uint8_t *buf, int size, uint32_t *bytes_written)
{
switch (openjtag_variant) {
case OPENJTAG_VARIANT_CY7C65215:
return openjtag_buf_write_cy7c65215(buf, size, bytes_written);
default:
return openjtag_buf_write_standard(buf, size, bytes_written);
}
}
static int openjtag_buf_read_standard(
uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
{
int retval;
int timeout = 5;
@@ -287,10 +303,53 @@ static int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);
#endif
#endif
return ERROR_OK;
}
static int openjtag_buf_read_cy7c65215(
uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
{
int ret;
if (qty == 0) {
*bytes_read = 0;
goto out;
}
ret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,
CY7C65215_JTAG_READ, qty, 0,
NULL, 0, CY7C65215_USB_TIMEOUT);
if (ret < 0) {
LOG_ERROR("vendor command failed, error %d", ret);
return ERROR_JTAG_DEVICE_ERROR;
}
ret = jtag_libusb_bulk_read(usbh, ep_in, (char *)buf, qty,
CY7C65215_USB_TIMEOUT);
if (ret < 0) {
LOG_ERROR("bulk read failed, error %d", ret);
return ERROR_JTAG_DEVICE_ERROR;
}
*bytes_read = ret;
out:
#ifdef _DEBUG_USB_COMMS_
openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);
#endif
return ERROR_OK;
}
static int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
{
switch (openjtag_variant) {
case OPENJTAG_VARIANT_CY7C65215:
return openjtag_buf_read_cy7c65215(buf, qty, bytes_read);
default:
return openjtag_buf_read_standard(buf, qty, bytes_read);
}
}
static int openjtag_sendcommand(uint8_t cmd)
{
uint32_t written;
@@ -335,109 +394,17 @@ static int openjtag_speed(int speed)
return ERROR_OK;
}
static int openjtag_init(void)
static int openjtag_init_standard(void)
{
uint8_t latency_timer;
#if BUILD_OPENJTAG_FTD2XX == 1
FT_STATUS status;
#endif
usb_tx_buf_offs = 0;
usb_rx_buf_len = 0;
openjtag_scan_result_count = 0;
#if BUILD_OPENJTAG_FTD2XX == 1
LOG_DEBUG("'openjtag' interface using FTD2XX");
#elif BUILD_OPENJTAG_LIBFTDI == 1
LOG_DEBUG("'openjtag' interface using libftdi");
#endif
/* Open by device description */
if (openjtag_device_desc == NULL) {
LOG_WARNING("no openjtag device description specified, "
/* Open by device description */
if (openjtag_device_desc == NULL) {
LOG_WARNING("no openjtag device description specified, "
"using default 'Open JTAG Project'");
openjtag_device_desc = "Open JTAG Project";
}
#if BUILD_OPENJTAG_FTD2XX == 1
#if IS_WIN32 == 0
/* Add non-standard Vid/Pid to the linux driver */
status = FT_SetVIDPID(openjtag_vid, openjtag_pid);
if (status != FT_OK) {
LOG_WARNING("couldn't add %4.4x:%4.4x",
openjtag_vid, openjtag_pid);
}
#endif
status = FT_OpenEx(openjtag_device_desc, FT_OPEN_BY_DESCRIPTION,
&ftdih);
if (status != FT_OK) {
DWORD num_devices;
LOG_ERROR("unable to open ftdi device: %u", status);
status = FT_ListDevices(&num_devices, NULL,
FT_LIST_NUMBER_ONLY);
if (status == FT_OK) {
char **desc_array = malloc(sizeof(char *)
* (num_devices + 1));
unsigned int i;
for (i = 0; i < num_devices; i++)
desc_array[i] = malloc(64);
desc_array[num_devices] = NULL;
status = FT_ListDevices(desc_array, &num_devices,
FT_LIST_ALL | FT_OPEN_BY_DESCRIPTION);
if (status == FT_OK) {
LOG_ERROR("ListDevices: %u\n", num_devices);
for (i = 0; i < num_devices; i++)
LOG_ERROR("%i: %s", i, desc_array[i]);
}
for (i = 0; i < num_devices; i++)
free(desc_array[i]);
free(desc_array);
} else {
LOG_ERROR("ListDevices: NONE\n");
}
return ERROR_JTAG_INIT_FAILED;
openjtag_device_desc = "Open JTAG Project";
}
status = FT_SetLatencyTimer(ftdih, 2);
if (status != FT_OK) {
LOG_ERROR("unable to set latency timer: %u", status);
return ERROR_JTAG_INIT_FAILED;
}
status = FT_GetLatencyTimer(ftdih, &latency_timer);
if (status != FT_OK) {
LOG_ERROR("unable to get latency timer: %u", status);
return ERROR_JTAG_INIT_FAILED;
}
LOG_DEBUG("current latency timer: %i", latency_timer);
status = FT_SetBitMode(ftdih, 0x00, 0x40);
if (status != FT_OK) {
LOG_ERROR("unable to disable bit i/o mode: %u", status);
return ERROR_JTAG_INIT_FAILED;
}
status = FT_SetTimeouts(ftdih, 50, 0);
if (status != FT_OK) {
LOG_ERROR("unable to set timeouts: %u", status);
return ERROR_JTAG_INIT_FAILED;
}
status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX);
if (status != FT_OK) {
LOG_ERROR("unable to FT_Purge() %u", status);
return ERROR_JTAG_INIT_FAILED;
}
#elif BUILD_OPENJTAG_LIBFTDI == 1
if (ftdi_init(&ftdic) < 0)
return ERROR_JTAG_INIT_FAILED;
@@ -470,38 +437,107 @@ if (openjtag_device_desc == NULL) {
ftdi_get_error_string(&ftdic));
return ERROR_JTAG_DEVICE_ERROR;
}
#endif
#if BUILD_OPENJTAG_FTD2XX == 1
status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX);
if (status != FT_OK)
return ERROR_JTAG_INIT_FAILED;
#elif BUILD_OPENJTAG_LIBFTDI == 1
if (ftdi_usb_purge_buffers(&ftdic) < 0) {
LOG_ERROR("ftdi_purge_buffers: %s", ftdic.error_str);
return ERROR_JTAG_INIT_FAILED;
}
#endif
/* OpenJTAG speed */
openjtag_sendcommand(0xE0); /*Start at slowest adapter speed*/
return ERROR_OK;
}
/* MSB */
openjtag_sendcommand(0x75);
static int openjtag_init_cy7c65215(void)
{
int ret;
usbh = NULL;
ret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, NULL, &usbh);
if (ret != ERROR_OK) {
LOG_ERROR("unable to open cy7c65215 device");
goto err;
}
ret = jtag_libusb_choose_interface(usbh, &ep_in, &ep_out,
CY7C65215_JTAG_CLASS,
CY7C65215_JTAG_SUBCLASS, -1, LIBUSB_TRANSFER_TYPE_BULK);
if (ret != ERROR_OK) {
LOG_ERROR("unable to claim JTAG interface");
goto err;
}
ret = jtag_libusb_control_transfer(usbh,
CY7C65215_JTAG_REQUEST,
CY7C65215_JTAG_ENABLE,
0, 0, NULL, 0, CY7C65215_USB_TIMEOUT);
if (ret < 0) {
LOG_ERROR("could not enable JTAG module");
goto err;
}
return ERROR_OK;
err:
if (usbh != NULL)
jtag_libusb_close(usbh);
return ERROR_JTAG_INIT_FAILED;
}
static int openjtag_init(void)
{
int ret;
usb_tx_buf_offs = 0;
usb_rx_buf_len = 0;
openjtag_scan_result_count = 0;
switch (openjtag_variant) {
case OPENJTAG_VARIANT_CY7C65215:
ret = openjtag_init_cy7c65215();
break;
default:
ret = openjtag_init_standard();
}
if (ret != ERROR_OK)
return ret;
openjtag_speed(375); /* Start at slowest adapter speed */
openjtag_sendcommand(0x75); /* MSB */
return ERROR_OK;
}
static int openjtag_quit_standard(void)
{
ftdi_usb_close(&ftdic);
ftdi_deinit(&ftdic);
return ERROR_OK;
}
static int openjtag_quit_cy7c65215(void)
{
int ret;
ret = jtag_libusb_control_transfer(usbh,
CY7C65215_JTAG_REQUEST,
CY7C65215_JTAG_DISABLE,
0, 0, NULL, 0, CY7C65215_USB_TIMEOUT);
if (ret < 0)
LOG_WARNING("could not disable JTAG module");
jtag_libusb_close(usbh);
return ERROR_OK;
}
static int openjtag_quit(void)
{
#if BUILD_OPENJTAG_FTD2XX == 1
FT_Close(ftdih);
#elif BUILD_OPENJTAG_LIBFTDI == 1
ftdi_usb_close(&ftdic);
ftdi_deinit(&ftdic);
#endif
return ERROR_OK;
switch (openjtag_variant) {
case OPENJTAG_VARIANT_CY7C65215:
return openjtag_quit_cy7c65215();
default:
return openjtag_quit_standard();
}
}
static void openjtag_write_tap_buffer(void)
@@ -536,8 +572,8 @@ static int openjtag_execute_tap_queue(void)
uint8_t *buffer = openjtag_scan_result_buffer[res_count].buffer;
while (len) {
if (len <= 8) {
while (len > 0) {
if (len <= 8 && openjtag_variant != OPENJTAG_VARIANT_CY7C65215) {
DEBUG_JTAG_IO("bits < 8 buf = 0x%X, will be 0x%X",
usb_rx_buf[rx_offs], usb_rx_buf[rx_offs] >> (8 - len));
buffer[count] = usb_rx_buf[rx_offs] >> (8 - len);
@@ -724,11 +760,14 @@ static void openjtag_execute_runtest(struct jtag_command *cmd)
if (cmd->cmd.runtest->num_cycles > 16)
LOG_WARNING("num_cycles > 16 on run test");
uint8_t command;
command = 7;
command |= ((cmd->cmd.runtest->num_cycles - 1) & 0x0F) << 4;
if (openjtag_variant != OPENJTAG_VARIANT_CY7C65215 ||
cmd->cmd.runtest->num_cycles) {
uint8_t command;
command = 7;
command |= ((cmd->cmd.runtest->num_cycles - 1) & 0x0F) << 4;
openjtag_add_byte(command);
openjtag_add_byte(command);
}
tap_set_end_state(end_state);
if (tap_get_end_state() != tap_get_state()) {
@@ -816,6 +855,24 @@ COMMAND_HANDLER(openjtag_handle_device_desc_command)
return ERROR_OK;
}
COMMAND_HANDLER(openjtag_handle_variant_command)
{
if (CMD_ARGC == 1) {
const char * const *name = openjtag_variant_names;
int variant = 0;
for (; *name; name++, variant++) {
if (strcasecmp(CMD_ARGV[0], *name) == 0) {
openjtag_variant = variant;
return ERROR_OK;
}
}
LOG_ERROR("unknown openjtag variant '%s'", CMD_ARGV[0]);
} else {
LOG_ERROR("require exactly one argument to "
"openjtag_variant <variant>");
}
return ERROR_OK;
}
static const struct command_registration openjtag_command_handlers[] = {
{
@@ -825,6 +882,13 @@ static const struct command_registration openjtag_command_handlers[] = {
.help = "set the USB device description of the OpenJTAG",
.usage = "description-string",
},
{
.name = "openjtag_variant",
.handler = openjtag_handle_variant_command,
.mode = COMMAND_CONFIG,
.help = "set the OpenJTAG variant",
.usage = "variant-string",
},
COMMAND_REGISTRATION_DONE
};
-219
View File
@@ -34,14 +34,7 @@
#include "bitq.h"
/* PRESTO access library includes */
#if BUILD_PRESTO_FTD2XX == 1
#include <ftd2xx.h>
#include "ftd2xx_common.h"
#elif BUILD_PRESTO_LIBFTDI == 1
#include <ftdi.h>
#else
#error "BUG: either FTD2XX and LIBFTDI has to be used"
#endif
/* -------------------------------------------------------------------------- */
@@ -55,13 +48,8 @@
#define BUFFER_SIZE (64*62)
struct presto {
#if BUILD_PRESTO_FTD2XX == 1
FT_HANDLE handle;
FT_STATUS status;
#elif BUILD_PRESTO_LIBFTDI == 1
struct ftdi_context ftdic;
int retval;
#endif
char serial[FT_DEVICE_SERNUM_LEN];
@@ -95,15 +83,6 @@ static uint8_t presto_init_seq[] = {
static int presto_write(uint8_t *buf, uint32_t size)
{
#if BUILD_PRESTO_FTD2XX == 1
DWORD ftbytes;
presto->status = FT_Write(presto->handle, buf, size, &ftbytes);
if (presto->status != FT_OK) {
LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(presto->status));
return ERROR_JTAG_DEVICE_ERROR;
}
#elif BUILD_PRESTO_LIBFTDI == 1
uint32_t ftbytes;
presto->retval = ftdi_write_data(&presto->ftdic, buf, size);
if (presto->retval < 0) {
@@ -111,7 +90,6 @@ static int presto_write(uint8_t *buf, uint32_t size)
return ERROR_JTAG_DEVICE_ERROR;
}
ftbytes = presto->retval;
#endif
if (ftbytes != size) {
LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%u < %u)",
@@ -124,15 +102,6 @@ static int presto_write(uint8_t *buf, uint32_t size)
static int presto_read(uint8_t *buf, uint32_t size)
{
#if BUILD_PRESTO_FTD2XX == 1
DWORD ftbytes;
presto->status = FT_Read(presto->handle, buf, size, &ftbytes);
if (presto->status != FT_OK) {
LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(presto->status));
return ERROR_JTAG_DEVICE_ERROR;
}
#elif BUILD_PRESTO_LIBFTDI == 1
uint32_t ftbytes = 0;
struct timeval timeout, now;
@@ -152,7 +121,6 @@ static int presto_read(uint8_t *buf, uint32_t size)
((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec)))
break;
}
#endif
if (ftbytes != size) {
/* this is just a warning, there might have been timeout when detecting PRESTO,
@@ -165,150 +133,6 @@ static int presto_read(uint8_t *buf, uint32_t size)
return ERROR_OK;
}
#if BUILD_PRESTO_FTD2XX == 1
static int presto_open_ftd2xx(char *req_serial)
{
uint32_t i;
DWORD numdevs;
DWORD vidpid;
char devname[FT_DEVICE_NAME_LEN];
FT_DEVICE device;
BYTE presto_data;
DWORD ftbytes;
presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
#if IS_WIN32 == 0
/* Add non-standard Vid/Pid to the linux driver */
presto->status = FT_SetVIDPID(PRESTO_VID, PRESTO_PID);
if (presto->status != FT_OK) {
LOG_ERROR("couldn't add PRESTO VID/PID");
exit(-1);
}
#endif
presto->status = FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY);
if (presto->status != FT_OK) {
LOG_ERROR("FT_ListDevices failed: %s", ftd2xx_status_string(presto->status));
return ERROR_JTAG_DEVICE_ERROR;
}
LOG_DEBUG("FTDI devices available: %" PRIu32, (uint32_t)numdevs);
for (i = 0; i < numdevs; i++) {
presto->status = FT_Open(i, &(presto->handle));
if (presto->status != FT_OK) {
/* this is not fatal, the device may be legitimately open by other process,
*hence debug message only */
LOG_DEBUG("FT_Open failed: %s", ftd2xx_status_string(presto->status));
continue;
}
LOG_DEBUG("FTDI device %i open", (int)i);
presto->status = FT_GetDeviceInfo(presto->handle, &device,
&vidpid, presto->serial, devname, NULL);
if (presto->status == FT_OK) {
if (vidpid == PRESTO_VID_PID && (req_serial == NULL ||
!strcmp(presto->serial, req_serial)))
break;
} else
LOG_DEBUG("FT_GetDeviceInfo failed: %s", ftd2xx_status_string(
presto->status));
LOG_DEBUG("FTDI device %i does not match, closing", (int)i);
FT_Close(presto->handle);
presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
}
if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
return ERROR_JTAG_DEVICE_ERROR; /* presto not open, return */
presto->status = FT_SetLatencyTimer(presto->handle, 1);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
presto->status = FT_SetTimeouts(presto->handle, 100, 0);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
presto_data = 0xD0;
presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
/* delay between first write/read turnaround (after purge?) necessary
* under Linux for unknown reason,
* probably a bug in library threading */
usleep(100000);
presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
if (ftbytes != 1) {
LOG_DEBUG("PRESTO reset");
presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
presto->status = FT_SetBitMode(presto->handle, 0x80, 1);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
presto->status = FT_SetBaudRate(presto->handle, 9600);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
presto_data = 0;
for (i = 0; i < 4 * 62; i++) {
presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
}
usleep(100000);
presto->status = FT_SetBitMode(presto->handle, 0x00, 0);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
presto_data = 0xD0;
presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
/* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
probably a bug in library threading */
usleep(100000);
presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
if (ftbytes != 1) {
LOG_DEBUG("PRESTO not responding");
return ERROR_JTAG_DEVICE_ERROR;
}
}
presto->status = FT_SetTimeouts(presto->handle, 0, 0);
if (presto->status != FT_OK)
return ERROR_JTAG_DEVICE_ERROR;
presto->status = FT_Write(presto->handle, &presto_init_seq,
sizeof(presto_init_seq), &ftbytes);
if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
return ERROR_JTAG_DEVICE_ERROR;
return ERROR_OK;
}
#elif BUILD_PRESTO_LIBFTDI == 1
static int presto_open_libftdi(char *req_serial)
{
uint8_t presto_data;
@@ -371,7 +195,6 @@ static int presto_open_libftdi(char *req_serial)
return ERROR_OK;
}
#endif /* BUILD_PRESTO_LIBFTDI == 1 */
static int presto_open(char *req_serial)
{
@@ -391,11 +214,7 @@ static int presto_open(char *req_serial)
presto->jtag_speed = 0;
#if BUILD_PRESTO_FTD2XX == 1
return presto_open_ftd2xx(req_serial);
#elif BUILD_PRESTO_LIBFTDI == 1
return presto_open_libftdi(req_serial);
#endif
}
static int presto_close(void)
@@ -403,35 +222,6 @@ static int presto_close(void)
int result = ERROR_OK;
#if BUILD_PRESTO_FTD2XX == 1
DWORD ftbytes;
if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
return result;
presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
if (presto->status != FT_OK)
result = ERROR_JTAG_DEVICE_ERROR;
presto->status = FT_Write(presto->handle,
&presto_init_seq,
sizeof(presto_init_seq),
&ftbytes);
if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
result = ERROR_JTAG_DEVICE_ERROR;
presto->status = FT_SetLatencyTimer(presto->handle, 16);
if (presto->status != FT_OK)
result = ERROR_JTAG_DEVICE_ERROR;
presto->status = FT_Close(presto->handle);
if (presto->status != FT_OK)
result = ERROR_JTAG_DEVICE_ERROR;
else
presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
#elif BUILD_PRESTO_LIBFTDI == 1
presto->retval = ftdi_write_data(&presto->ftdic, presto_init_seq, sizeof(presto_init_seq));
if (presto->retval != sizeof(presto_init_seq))
result = ERROR_JTAG_DEVICE_ERROR;
@@ -445,7 +235,6 @@ static int presto_close(void)
result = ERROR_JTAG_DEVICE_ERROR;
else
ftdi_deinit(&presto->ftdic);
#endif
return result;
}
@@ -455,11 +244,7 @@ static int presto_flush(void)
if (presto->buff_out_pos == 0)
return ERROR_OK;
#if BUILD_PRESTO_FTD2XX == 1
if (presto->status != FT_OK) {
#elif BUILD_PRESTO_LIBFTDI == 1
if (presto->retval < 0) {
#endif
LOG_DEBUG("error in previous communication, canceling I/O operation");
return ERROR_JTAG_DEVICE_ERROR;
}
@@ -502,13 +287,9 @@ static int presto_sendbyte(int data)
} else
return ERROR_JTAG_DEVICE_ERROR;
#if BUILD_PRESTO_FTD2XX == 1
if (presto->buff_out_pos >= BUFFER_SIZE)
#elif BUILD_PRESTO_LIBFTDI == 1
/* libftdi does not do background read, be sure that USB IN buffer does not overflow (128
*bytes only!) */
if (presto->buff_out_pos >= BUFFER_SIZE || presto->buff_in_exp == 128)
#endif
return presto_flush();
return ERROR_OK;
+1 -1
View File
@@ -216,7 +216,7 @@ struct stlink_usb_handle_s {
#define STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH 0x01
#define STLINK_DEBUG_APIV2_DRIVE_NRST_PULSE 0x02
#define STLINK_TRACE_SIZE 1024
#define STLINK_TRACE_SIZE 4096
#define STLINK_TRACE_MAX_HZ 2000000
#define STLINK_TRACE_MIN_VERSION 13
+6 -5
View File
@@ -242,7 +242,8 @@ static int icdi_send_remote_cmd(void *handle, const char *data)
struct icdi_usb_handle_s *h = handle;
size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,");
cmd_len += hexify(h->write_buffer + cmd_len, data, 0, h->max_packet - cmd_len);
cmd_len += hexify(h->write_buffer + cmd_len, (const uint8_t *)data,
strlen(data), h->max_packet - cmd_len);
return icdi_send_packet(handle, cmd_len);
}
@@ -266,7 +267,7 @@ static int icdi_get_cmd_result(void *handle)
if (h->read_buffer[offset] == 'E') {
/* get error code */
char result;
uint8_t result;
if (unhexify(&result, h->read_buffer + offset + 1, 1) != 1)
return ERROR_FAIL;
return result;
@@ -328,7 +329,7 @@ static int icdi_usb_version(void *handle)
}
/* convert reply */
if (unhexify(version, h->read_buffer + 2, 4) != 4) {
if (unhexify((uint8_t *)version, h->read_buffer + 2, 4) != 4) {
LOG_WARNING("unable to get ICDI version");
return ERROR_OK;
}
@@ -495,7 +496,7 @@ static int icdi_usb_read_reg(void *handle, int num, uint32_t *val)
/* convert result */
uint8_t buf[4];
if (unhexify((char *)buf, h->read_buffer + 2, 4) != 4) {
if (unhexify(buf, h->read_buffer + 2, 4) != 4) {
LOG_ERROR("failed to convert result");
return ERROR_FAIL;
}
@@ -512,7 +513,7 @@ static int icdi_usb_write_reg(void *handle, int num, uint32_t val)
h_u32_to_le(buf, val);
int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", num);
hexify(cmd + cmd_len, (const char *)buf, 4, sizeof(cmd));
hexify(cmd + cmd_len, buf, 4, sizeof(cmd));
result = icdi_send_cmd(handle, cmd);
if (result != ERROR_OK)
+1 -1
View File
@@ -2066,7 +2066,7 @@ static int ulink_khz(int khz, int *jtag_speed)
}
#ifdef _DEBUG_JTAG_IO_
long f_tck, f_tms, f_scan_in, f_scan_out, f_scan_io;
long f_tck = 0, f_tms = 0, f_scan_in = 0, f_scan_out = 0, f_scan_io = 0;
ulink_calculate_frequency(DELAY_CLOCK_TCK, ulink_handle->delay_clock_tck,
&f_tck);
+7 -18
View File
@@ -1,24 +1,13 @@
include $(top_srcdir)/common.mk
noinst_LTLIBRARIES += %D%/libocdusbblaster.la
%C%_libocdusbblaster_la_SOURCES = $(USB_BLASTER_SRC)
%C%_libocdusbblaster_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS)
AM_CPPFLAGS += -I$(top_srcdir)/src/jtag/drivers $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS)
USB_BLASTER_SRC = %D%/usb_blaster.c %D%/ublast_access.h
noinst_LTLIBRARIES = libocdusbblaster.la
libocdusbblaster_la_SOURCES = $(USB_BLASTER_SRC)
USB_BLASTER_SRC = usb_blaster.c
if USB_BLASTER_LIBFTDI
USB_BLASTER_SRC += ublast_access_ftdi.c
endif
if USB_BLASTER_FTD2XX
USB_BLASTER_SRC += ublast_access_ftd2xx.c
if USB_BLASTER
USB_BLASTER_SRC += %D%/ublast_access_ftdi.c
endif
if USB_BLASTER_2
USB_BLASTER_SRC += ublast2_access_libusb.c
USB_BLASTER_SRC += %D%/ublast2_access_libusb.c
endif
noinst_HEADERS = ublast_access.h
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+2 -5
View File
@@ -56,19 +56,16 @@ struct ublast_lowlevel {
/**
* ublast_register_ftdi - get a lowlevel USB Blaster driver
* ublast_register_ftd2xx - get a lowlevel USB Blaster driver
* ublast2_register_libusb - get a lowlevel USB Blaster II driver
*
* Get a lowlevel USB-Blaster driver. In the current implementation, there are 3
* Get a lowlevel USB-Blaster driver. In the current implementation, there are 2
* possible lowlevel drivers :
* - one based on libftdi from ftdichip.com
* - one based on libftdxx, the free alternative
* - one based on libftdi,
* - one based on libusb, specific to the USB-Blaster II
*
* Returns the lowlevel driver structure.
*/
extern struct ublast_lowlevel *ublast_register_ftdi(void);
extern struct ublast_lowlevel *ublast_register_ftd2xx(void);
extern struct ublast_lowlevel *ublast2_register_libusb(void);
#endif /* OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H */
@@ -1,180 +0,0 @@
/*
* Driver for USB-JTAG, Altera USB-Blaster and compatibles
*
* Inspired from original code from Kolja Waschk's USB-JTAG project
* (http://www.ixo.de/info/usb_jtag/), and from openocd project.
*
* Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr
* Copyright (C) 2011 Ali Lown ali@lown.me.uk
* Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca
* Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <jtag/interface.h>
#include <jtag/commands.h>
#include "ublast_access.h"
#include <ftd2xx.h>
#include "jtag/drivers/ftd2xx_common.h"
static FT_HANDLE *ublast_getftdih(struct ublast_lowlevel *low)
{
return low->priv;
}
static int ublast_ftd2xx_write(struct ublast_lowlevel *low, uint8_t *buf, int size,
uint32_t *bytes_written)
{
FT_STATUS status;
DWORD dw_bytes_written;
FT_HANDLE *ftdih = ublast_getftdih(low);
status = FT_Write(*ftdih, buf, size, &dw_bytes_written);
if (status != FT_OK) {
*bytes_written = dw_bytes_written;
LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(status));
return ERROR_JTAG_DEVICE_ERROR;
}
*bytes_written = dw_bytes_written;
return ERROR_OK;
}
static int ublast_ftd2xx_read(struct ublast_lowlevel *low, uint8_t *buf,
unsigned size, uint32_t *bytes_read)
{
DWORD dw_bytes_read;
FT_STATUS status;
FT_HANDLE *ftdih = ublast_getftdih(low);
status = FT_Read(*ftdih, buf, size, &dw_bytes_read);
if (status != FT_OK) {
*bytes_read = dw_bytes_read;
LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(status));
return ERROR_JTAG_DEVICE_ERROR;
}
*bytes_read = dw_bytes_read;
return ERROR_OK;
}
static int ublast_ftd2xx_init(struct ublast_lowlevel *low)
{
FT_STATUS status;
FT_HANDLE *ftdih = ublast_getftdih(low);
uint8_t latency_timer;
LOG_INFO("usb blaster interface using FTD2XX");
/* Open by device description */
if (low->ublast_device_desc == NULL) {
LOG_WARNING("no usb blaster device description specified, "
"using default 'USB-Blaster'");
low->ublast_device_desc = "USB-Blaster";
}
#if IS_WIN32 == 0
/* Add non-standard Vid/Pid to the linux driver */
status = FT_SetVIDPID(low->ublast_vid, low->ublast_pid);
if (status != FT_OK) {
LOG_WARNING("couldn't add %4.4x:%4.4x",
low->ublast_vid, low->ublast_pid);
}
#endif
status = FT_OpenEx(low->ublast_device_desc, FT_OPEN_BY_DESCRIPTION,
ftdih);
if (status != FT_OK) {
DWORD num_devices;
LOG_ERROR("unable to open ftdi device: %s",
ftd2xx_status_string(status));
status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY);
if (status == FT_OK) {
char **desc_array =
malloc(sizeof(char *) * (num_devices + 1));
unsigned int i;
for (i = 0; i < num_devices; i++)
desc_array[i] = malloc(64);
desc_array[num_devices] = NULL;
status = FT_ListDevices(desc_array, &num_devices,
FT_LIST_ALL | FT_OPEN_BY_DESCRIPTION);
if (status == FT_OK) {
LOG_ERROR("ListDevices: %" PRIu32, (uint32_t)num_devices);
for (i = 0; i < num_devices; i++)
LOG_ERROR("%i: %s", i, desc_array[i]);
}
for (i = 0; i < num_devices; i++)
free(desc_array[i]);
free(desc_array);
} else {
printf("ListDevices: NONE\n");
}
return ERROR_JTAG_INIT_FAILED;
}
status = FT_SetLatencyTimer(*ftdih, 2);
if (status != FT_OK) {
LOG_ERROR("unable to set latency timer: %s",
ftd2xx_status_string(status));
return ERROR_JTAG_INIT_FAILED;
}
status = FT_GetLatencyTimer(*ftdih, &latency_timer);
if (status != FT_OK)
LOG_ERROR("unable to get latency timer: %s",
ftd2xx_status_string(status));
else
LOG_DEBUG("current latency timer: %i", latency_timer);
status = FT_SetBitMode(*ftdih, 0x00, 0);
if (status != FT_OK) {
LOG_ERROR("unable to disable bit i/o mode: %s",
ftd2xx_status_string(status));
return ERROR_JTAG_INIT_FAILED;
}
return ERROR_OK;
}
static int ublast_ftd2xx_quit(struct ublast_lowlevel *low)
{
FT_HANDLE *ftdih = ublast_getftdih(low);
FT_Close(*ftdih);
return ERROR_OK;
}
static struct ublast_lowlevel_priv {
FT_HANDLE ftdih;
} info;
static struct ublast_lowlevel low = {
.open = ublast_ftd2xx_init,
.close = ublast_ftd2xx_quit,
.read = ublast_ftd2xx_read,
.write = ublast_ftd2xx_write,
.priv = &info,
};
struct ublast_lowlevel *ublast_register_ftd2xx(void)
{
return &low;
}
+3 -6
View File
@@ -147,12 +147,9 @@ struct drvs_map {
};
static struct drvs_map lowlevel_drivers_map[] = {
#if BUILD_USB_BLASTER_LIBFTDI
#if BUILD_USB_BLASTER
{ .name = "ftdi", .drv_register = ublast_register_ftdi },
#endif
#if BUILD_USB_BLASTER_FTD2XX
{ .name = "ftd2xx", .drv_register = ublast_register_ftd2xx },
#endif
#if BUILD_USB_BLASTER_2
{ .name = "ublast2", .drv_register = ublast2_register_libusb },
#endif
@@ -1048,8 +1045,8 @@ static const struct command_registration ublast_command_handlers[] = {
.name = "usb_blaster_lowlevel_driver",
.handler = ublast_handle_lowlevel_drv_command,
.mode = COMMAND_CONFIG,
.help = "set the lowlevel access for the USB Blaster (ftdi, ftd2xx, ublast2)",
.usage = "(ftdi|ftd2xx|ublast2)",
.help = "set the lowlevel access for the USB Blaster (ftdi, ublast2)",
.usage = "(ftdi|ublast2)",
},
{
.name = "usb_blaster_pin",
+10 -22
View File
@@ -1,23 +1,11 @@
include $(top_srcdir)/common.mk
noinst_LTLIBRARIES += %D%/libocdhla.la
noinst_LTLIBRARIES = libocdhla.la
libocdhla_la_SOURCES = \
$(HLFILES)
HLFILES =
if HLADAPTER
HLFILES += hla_transport.c
HLFILES += hla_tcl.c
HLFILES += hla_interface.c
HLFILES += hla_layout.c
endif
noinst_HEADERS = \
hla_interface.h \
hla_layout.h \
hla_tcl.h \
hla_transport.h
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
%C%_libocdhla_la_SOURCES = \
%D%/hla_transport.c \
%D%/hla_tcl.c \
%D%/hla_interface.c \
%D%/hla_layout.c \
%D%/hla_transport.h \
%D%/hla_interface.h \
%D%/hla_layout.h \
%D%/hla_tcl.h
+16 -16
View File
@@ -51,16 +51,10 @@ extern struct jtag_interface parport_interface;
#if BUILD_DUMMY == 1
extern struct jtag_interface dummy_interface;
#endif
#if BUILD_FT2232_FTD2XX == 1
extern struct jtag_interface ft2232_interface;
#endif
#if BUILD_FT2232_LIBFTDI == 1
extern struct jtag_interface ft2232_interface;
#endif
#if BUILD_FTDI == 1
extern struct jtag_interface ftdi_interface;
#endif
#if BUILD_USB_BLASTER_LIBFTDI == 1 || BUILD_USB_BLASTER_FTD2XX == 1 || BUILD_USB_BLASTER_2 == 1
#if BUILD_USB_BLASTER == 1 || BUILD_USB_BLASTER_2 == 1
extern struct jtag_interface usb_blaster_interface;
#endif
#if BUILD_JTAG_VPI == 1
@@ -78,7 +72,7 @@ extern struct jtag_interface at91rm9200_interface;
#if BUILD_GW16012 == 1
extern struct jtag_interface gw16012_interface;
#endif
#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
#if BUILD_PRESTO
extern struct jtag_interface presto_interface;
#endif
#if BUILD_USBPROG == 1
@@ -129,6 +123,12 @@ extern struct jtag_interface bcm2835gpio_interface;
#if BUILD_CMSIS_DAP == 1
extern struct jtag_interface cmsis_dap_interface;
#endif
#if BUILD_KITPROG == 1
extern struct jtag_interface kitprog_interface;
#endif
#if BUILD_IMX_GPIO == 1
extern struct jtag_interface imx_gpio_interface;
#endif
#endif /* standard drivers */
/**
@@ -150,16 +150,10 @@ struct jtag_interface *jtag_interfaces[] = {
#if BUILD_DUMMY == 1
&dummy_interface,
#endif
#if BUILD_FT2232_FTD2XX == 1
&ft2232_interface,
#endif
#if BUILD_FT2232_LIBFTDI == 1
&ft2232_interface,
#endif
#if BUILD_FTDI == 1
&ftdi_interface,
#endif
#if BUILD_USB_BLASTER_LIBFTDI == 1 || BUILD_USB_BLASTER_FTD2XX == 1 || BUILD_USB_BLASTER_2 == 1
#if BUILD_USB_BLASTER || BUILD_USB_BLASTER_2 == 1
&usb_blaster_interface,
#endif
#if BUILD_JTAG_VPI == 1
@@ -177,7 +171,7 @@ struct jtag_interface *jtag_interfaces[] = {
#if BUILD_GW16012 == 1
&gw16012_interface,
#endif
#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
#if BUILD_PRESTO
&presto_interface,
#endif
#if BUILD_USBPROG == 1
@@ -228,6 +222,12 @@ struct jtag_interface *jtag_interfaces[] = {
#if BUILD_CMSIS_DAP == 1
&cmsis_dap_interface,
#endif
#if BUILD_KITPROG == 1
&kitprog_interface,
#endif
#if BUILD_IMX_GPIO == 1
&imx_gpio_interface,
#endif
#endif /* standard drivers */
NULL,
};