kopia lustrzana https://github.com/stlink-org/stlink
Merge branch 'master' into local/stm32l_flash
commit
ebaf5ac5be
2
AUTHORS
2
AUTHORS
|
@ -7,3 +7,5 @@ karlp@tweak.net.au
|
|||
h0rr0rrdrag@gmail.com
|
||||
mstempin@com1.fr
|
||||
bon@elektron.ikp.physik.tu-darmstadt.de
|
||||
nelsonjm@macpod.neta
|
||||
ned@bike-nomad.com
|
41
Makefile
41
Makefile
|
@ -1,21 +1,36 @@
|
|||
|
||||
# make ... for both libusb and libsg
|
||||
#
|
||||
# make CONFIG_USE_LIBSG=0 ...
|
||||
# for just libusb
|
||||
#
|
||||
VPATH=src
|
||||
|
||||
SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c
|
||||
SOURCES_LIB=stlink-common.c stlink-usb.c
|
||||
OBJS_LIB=$(SOURCES_LIB:.c=.o)
|
||||
TEST_PROGRAMS=test_usb
|
||||
LDFLAGS=-lusb-1.0 -L. -lstlink
|
||||
|
||||
ifeq ($(CONFIG_USE_LIBSG),)
|
||||
CONFIG_USE_LIBSG=1
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_USE_LIBSG),0)
|
||||
SOURCES_LIB+=stlink-sg.c
|
||||
CFLAGS+=-DCONFIG_USE_LIBSG=1
|
||||
LDFLAGS+=-lsgutils2
|
||||
TEST_PROGRAMS+=test_sg
|
||||
endif
|
||||
|
||||
CFLAGS+=-g
|
||||
CFLAGS+=-DCONFIG_USE_LIBUSB
|
||||
CFLAGS+=-DCONFIG_USE_LIBSG
|
||||
CFLAGS+=-DDEBUG
|
||||
CFLAGS+=-DCONFIG_USE_LIBUSB=1
|
||||
CFLAGS+=-DDEBUG=1
|
||||
CFLAGS+=-std=gnu99
|
||||
CFLAGS+=-Wall -Wextra
|
||||
|
||||
LDFLAGS=-lstlink -lusb-1.0 -lsgutils2 -L.
|
||||
|
||||
LIBRARY=libstlink.a
|
||||
|
||||
all: $(LIBRARY) test_usb test_sg
|
||||
all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS)
|
||||
|
||||
$(LIBRARY): $(OBJS_LIB)
|
||||
@echo "objs are $(OBJS_LIB)"
|
||||
|
@ -43,4 +58,14 @@ clean:
|
|||
rm -rf test_usb*
|
||||
rm -rf test_sg*
|
||||
|
||||
.PHONY: clean all
|
||||
distclean: clean
|
||||
$(MAKE) -C flash clean
|
||||
$(MAKE) -C gdbserver clean
|
||||
|
||||
flash:
|
||||
$(MAKE) -C flash CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)"
|
||||
|
||||
gdbserver:
|
||||
$(MAKE) -C gdbserver
|
||||
|
||||
.PHONY: clean all flash gdbserver
|
||||
|
|
Plik binarny nie jest wyświetlany.
|
@ -56,12 +56,15 @@ point of view, those versions differ only in the transport layer used to communi
|
|||
(v1 uses SCSI passthru commands, while v2 uses raw USB).
|
||||
|
||||
\paragraph{}
|
||||
Before continuing, the following dependencies are required:
|
||||
Before continuing, the following dependencies must be met:
|
||||
\begin{itemize}
|
||||
\item libusb-1.0
|
||||
\item libsg2
|
||||
\item libsgutils2 (optionnal)
|
||||
\end{itemize}
|
||||
|
||||
\paragraph{}
|
||||
STLINK should run on any system meeting the above constraints.
|
||||
|
||||
\paragraph{}
|
||||
The STLINK software source code is retrieved using:\\
|
||||
\begin{small}
|
||||
|
@ -71,15 +74,19 @@ git clone https://github.com/texane/stlink stlink.git
|
|||
\end{small}
|
||||
|
||||
\paragraph{}
|
||||
The GDB server is called st-util and is built using:\\
|
||||
Everything can be built from the top directory:\\
|
||||
\begin{small}
|
||||
\begin{lstlisting}[frame=tb]
|
||||
$> cd stlink.git;
|
||||
$> make ;
|
||||
$> cd gdbserver ;
|
||||
$> cd stlink.git ;
|
||||
$> make ;
|
||||
\end{lstlisting}
|
||||
\end{small}
|
||||
It includes:
|
||||
\begin{itemize}
|
||||
\item a communication library (stlink.git/libstlink.a),
|
||||
\item a GDB server (stlink.git/gdbserver/st-util),
|
||||
\item a flash manipulation tool (stlink.git/flash/flash).
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\newpage
|
||||
|
@ -88,8 +95,9 @@ $> make ;
|
|||
A simple LED blinking example is provided in the example directory. It is built using:\\
|
||||
\begin{small}
|
||||
\begin{lstlisting}[frame=tb]
|
||||
# update the make option accordingly to your architecture
|
||||
cd stlink.git/example/blink ;
|
||||
PATH=$TOOLCHAIN_PATH/bin:$PATH make ;
|
||||
PATH=$TOOLCHAIN_PATH/bin:$PATH make CONFIG_STM32L_DISCOVERY=1;
|
||||
\end{lstlisting}
|
||||
\end{small}
|
||||
|
||||
|
@ -102,7 +110,8 @@ are using, you must run one of the 2 commands:\\
|
|||
$> sudo ./st-util /dev/sg2
|
||||
|
||||
# STM32L discovery kit
|
||||
$> sudo ./st-util
|
||||
# 2 dummy command line arguments needed, will be fixed soon
|
||||
$> sudo ./st-util fu bar
|
||||
\end{lstlisting}
|
||||
\end{small}
|
||||
|
||||
|
@ -151,8 +160,8 @@ Flash memory reading and writing is done by a separate tool. A binary running in
|
|||
be linked against address 0x8000000. The flash tool is then used as shown below:\\
|
||||
\begin{small}
|
||||
\begin{lstlisting}[frame=tb]
|
||||
# build the flash tool
|
||||
$> cd stlink.git/flash ; make ;
|
||||
# change to the flash tool directory
|
||||
$> cd stlink.git/flash ;
|
||||
|
||||
# stlinkv1 command to read 4096 from flash into out.bin
|
||||
$> ./flash read /dev/sg2 out.bin 0x8000000 4096
|
||||
|
@ -212,6 +221,17 @@ $> make
|
|||
\end{lstlisting}
|
||||
\end{small}
|
||||
|
||||
\subsection{STM32VL support}
|
||||
\paragraph{}
|
||||
It seems support for STM32VL is quite broken. If it does not work, try build STLINK using libsg:
|
||||
\begin{small}
|
||||
\begin{lstlisting}[frame=tb]
|
||||
$> cd stlink.git
|
||||
$> make CONFIG_USE_LIBSG=1
|
||||
\end{lstlisting}
|
||||
\end{small}
|
||||
|
||||
|
||||
\newpage
|
||||
\section{References}
|
||||
\begin{itemize}
|
||||
|
|
|
@ -4,8 +4,15 @@ BIN_IMAGE=blink.bin
|
|||
CC=arm-none-eabi-gcc
|
||||
OBJCOPY=arm-none-eabi-objcopy
|
||||
|
||||
CFLAGS=-O2 -mlittle-endian -mthumb
|
||||
CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc
|
||||
CFLAGS=-g -O2 -mlittle-endian -mthumb
|
||||
ifeq ($(CONFIG_STM32L_DISCOVERY), 1)
|
||||
CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY
|
||||
else ifeq ($(CONFIG_STM32VL_DISCOVERY), 1)
|
||||
CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32VL_DISCOVERY=1
|
||||
else ifeq ($(CONFIG_STM32F4_DISCOVERY), 1)
|
||||
CFLAGS+=-mcpu=cortex-m4 -DCONFIG_STM32F4_DISCOVERY=1
|
||||
endif
|
||||
CFLAGS+=-ffreestanding -nostdlib -nostdinc
|
||||
|
||||
# to run from SRAM
|
||||
CFLAGS+=-Wl,-Ttext,0x20000000 -Wl,-e,0x20000000
|
||||
|
|
|
@ -5,10 +5,6 @@ typedef unsigned int uint32_t;
|
|||
|
||||
/* hardware configuration */
|
||||
|
||||
#define CONFIG_STM32L_DISCOVERY 1
|
||||
#define CONFIG_STM32VL_DISCOVERY 0
|
||||
|
||||
|
||||
#if CONFIG_STM32VL_DISCOVERY
|
||||
|
||||
# define GPIOC 0x40011000 /* port C */
|
||||
|
@ -58,6 +54,36 @@ static inline void switch_leds_off(void)
|
|||
*(volatile uint32_t*)GPIOB_ODR = 0;
|
||||
}
|
||||
|
||||
#elif CONFIG_STM32F4_DISCOVERY
|
||||
|
||||
#define GPIOD 0x40020C00 /* port D */
|
||||
# define GPIOD_MODER (GPIOD + 0x00) /* port mode register */
|
||||
# define GPIOD_ODR (GPIOD + 0x14) /* port output data register */
|
||||
|
||||
# define LED_GREEN (1 << 12) /* port B, pin 12 */
|
||||
# define LED_ORANGE (1 << 13) /* port B, pin 13 */
|
||||
# define LED_RED (1 << 14) /* port B, pin 14 */
|
||||
# define LED_BLUE (1 << 15) /* port B, pin 15 */
|
||||
|
||||
static inline void setup_leds(void)
|
||||
{
|
||||
*(volatile uint32_t*)GPIOD_MODER |= (1 << (12 * 2)) | (1 << (13 * 2)) |
|
||||
(1 << (13 * 2)) | (1 << (14 * 2)) | (1 << (15 * 2));
|
||||
}
|
||||
|
||||
|
||||
static inline void switch_leds_on(void)
|
||||
{
|
||||
*(volatile uint32_t*)GPIOD_ODR = LED_GREEN | LED_ORANGE | LED_RED | LED_BLUE;
|
||||
}
|
||||
|
||||
static inline void switch_leds_off(void)
|
||||
{
|
||||
*(volatile uint32_t*)GPIOD_ODR = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#error "Architecture must be defined!"
|
||||
#endif /* otherwise, error */
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,18 @@ CC=arm-none-eabi-gcc
|
|||
OBJCOPY=arm-none-eabi-objcopy
|
||||
|
||||
CFLAGS=-O2 -mlittle-endian -mthumb
|
||||
CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc
|
||||
|
||||
CFLAGS=-g -O2 -mlittle-endian -mthumb
|
||||
ifeq ($(CONFIG_STM32L_DISCOVERY), 1)
|
||||
CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32L_DISCOVERY
|
||||
else ifeq ($(CONFIG_STM32VL_DISCOVERY), 1)
|
||||
CFLAGS+=-mcpu=cortex-m3 -DCONFIG_STM32VL_DISCOVERY=1
|
||||
else ifeq ($(CONFIG_STM32F4_DISCOVERY), 1)
|
||||
CFLAGS+=-mcpu=cortex-m4 -DCONFIG_STM32F4_DISCOVERY=1
|
||||
else
|
||||
$(error "must specify CONFIG_ for board!")
|
||||
endif
|
||||
CFLAGS+=-ffreestanding -nostdlib -nostdinc
|
||||
|
||||
# to run from FLASH
|
||||
CFLAGS+=-Wl,-T,stm32_flash.ld
|
||||
|
|
|
@ -1,14 +1,27 @@
|
|||
# make ... for both libusb and libsg
|
||||
#
|
||||
# make CONFIG_USE_LIBSG=0 ...
|
||||
# for just libusb
|
||||
#
|
||||
CC=gcc
|
||||
|
||||
CFLAGS+=-g
|
||||
CFLAGS+=-DCONFIG_USE_LIBUSB
|
||||
CFLAGS+=-DCONFIG_USE_LIBSG
|
||||
CFLAGS+=-DCONFIG_USE_LIBUSB=1
|
||||
CFLAGS+=-DDEBUG
|
||||
CFLAGS+=-std=gnu99
|
||||
CFLAGS+=-Wall -Wextra
|
||||
CFLAGS+=-I../src
|
||||
|
||||
LDFLAGS=-L.. -lstlink -lusb-1.0 -lsgutils2
|
||||
LDFLAGS=-lusb-1.0 -L.. -lstlink
|
||||
|
||||
ifeq ($(CONFIG_USE_LIBSG),)
|
||||
CONFIG_USE_LIBSG=1
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_USE_LIBSG),0)
|
||||
CFLAGS+=-DCONFIG_USE_LIBSG=1
|
||||
LDFLAGS+=-lsgutils2
|
||||
endif
|
||||
|
||||
SRCS=main.c
|
||||
OBJS=$(SRCS:.c=.o)
|
||||
|
|
13
flash/main.c
13
flash/main.c
|
@ -17,6 +17,11 @@ struct opts
|
|||
size_t size;
|
||||
};
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
puts("stlinkv1 command line: ./flash {read|write} /dev/sgX path addr <size>");
|
||||
puts("stlinkv2 command line: ./flash {read|write} path addr <size>");
|
||||
}
|
||||
|
||||
static int get_opts(struct opts* o, int ac, char** av)
|
||||
{
|
||||
|
@ -75,18 +80,24 @@ int main(int ac, char** av)
|
|||
if (get_opts(&o, ac - 1, av + 1) == -1)
|
||||
{
|
||||
printf("invalid command line\n");
|
||||
usage();
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
if (o.devname != NULL) /* stlinkv1 */
|
||||
{
|
||||
#if CONFIG_USE_LIBSG
|
||||
static const int scsi_verbose = 2;
|
||||
sl = stlink_quirk_open(o.devname, scsi_verbose);
|
||||
if (sl == NULL) goto on_error;
|
||||
#else
|
||||
printf("not compiled for use with STLink/V1");
|
||||
goto on_error;
|
||||
#endif
|
||||
}
|
||||
else /* stlinkv2 */
|
||||
{
|
||||
sl = stlink_open_usb(NULL, 10);
|
||||
sl = stlink_open_usb(10);
|
||||
if (sl == NULL) goto on_error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,24 @@
|
|||
# make ... for both libusb and libsg
|
||||
#
|
||||
# make CONFIG_USE_LIBSG=0 ...
|
||||
# for just libusb
|
||||
#
|
||||
|
||||
PRG := st-util
|
||||
OBJS = gdb-remote.o gdb-server.o
|
||||
|
||||
CFLAGS+=-g -Wall -Werror -std=gnu99 -I../src
|
||||
CFLAGS+=-DCONFIG_USE_LIBUSB
|
||||
CFLAGS+=-DCONFIG_USE_LIBSG
|
||||
LIBS := -lstlink -lusb-1.0 -lsgutils2
|
||||
LDFLAGS+=$(LIBS) -L..
|
||||
CFLAGS+=-DCONFIG_USE_LIBUSB=1
|
||||
LDFLAGS=-lusb-1.0 -L.. -lstlink
|
||||
|
||||
ifeq ($(CONFIG_USE_LIBSG),)
|
||||
CONFIG_USE_LIBSG=1
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_USE_LIBSG),0)
|
||||
CFLAGS+=-DCONFIG_USE_LIBSG=1
|
||||
LDFLAGS+=-lsgutils2
|
||||
endif
|
||||
|
||||
all: $(PRG)
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <stlink-common.h>
|
||||
|
||||
|
@ -24,6 +25,12 @@
|
|||
#define FLASH_PAGE_MASK (~((1 << 10) - 1))
|
||||
#define FLASH_SIZE (FLASH_PAGE * 128)
|
||||
|
||||
volatile int do_exit = 0;
|
||||
void ctrl_c(int sig)
|
||||
{
|
||||
do_exit = 1;
|
||||
}
|
||||
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
|
||||
static const char* current_memory_map = NULL;
|
||||
|
@ -32,6 +39,11 @@ static const char* current_memory_map = NULL;
|
|||
* Chip IDs are explained in the appropriate programming manual for the
|
||||
* DBGMCU_IDCODE register (0xE0042000)
|
||||
*/
|
||||
|
||||
#define CORE_M3_R1 0x1BA00477
|
||||
#define CORE_M3_R2 0x4BA00477
|
||||
#define CORE_M4_R0 0x2BA01477
|
||||
|
||||
struct chip_params {
|
||||
uint32_t chip_id;
|
||||
char* description;
|
||||
|
@ -43,11 +55,11 @@ struct chip_params {
|
|||
{ 0x410, "F1 Medium-density device", 0x1ffff7e0,
|
||||
0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, // table 2, pm0063
|
||||
{ 0x411, "F2 device", 0, /* No flash size register found in the docs*/
|
||||
0x100000, 0x20000, 0x20000, 0x1ff00000, 0x7800 }, // table 1, pm0059
|
||||
0x100000, 0x20000, 0x20000, 0x1fff0000, 0x7800 }, // table 1, pm0059
|
||||
{ 0x412, "F1 Low-density device", 0x1ffff7e0,
|
||||
0x8000, 0x400, 0x2800, 0x1ffff000, 0x800 }, // table 1, pm0063
|
||||
{ 0x413, "F4 device", 0x1FFF7A10,
|
||||
0x100000, 0x20000, 0x20000, 0x1ff00000, 0x7800 }, // table 1, pm0081
|
||||
0x100000, 0x20000, 0x30000, 0x1fff0000, 0x7800 }, // table 1, pm0081
|
||||
{ 0x414, "F1 High-density device", 0x1ffff7e0,
|
||||
0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, // table 3 pm0063
|
||||
// This ignores the EEPROM! (and uses the page erase size,
|
||||
|
@ -79,15 +91,10 @@ int main(int argc, char** argv) {
|
|||
|
||||
switch(argc) {
|
||||
|
||||
default: {
|
||||
fprintf(stderr, HelpStr, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case 3 : {
|
||||
//sl = stlink_quirk_open(argv[2], 0);
|
||||
// FIXME - hardcoded to usb....
|
||||
sl = stlink_open_usb(argv[2], 10);
|
||||
// FIXME - hardcoded to usb....
|
||||
sl = stlink_open_usb(10);
|
||||
if(sl == NULL) return 1;
|
||||
break;
|
||||
}
|
||||
|
@ -99,6 +106,7 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_USE_LIBSG
|
||||
case 1 : { // Search ST-LINK (from /dev/sg0 to /dev/sg99)
|
||||
const int DevNumMax = 99;
|
||||
int ExistDevCount = 0;
|
||||
|
@ -136,18 +144,32 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default: {
|
||||
fprintf(stderr, HelpStr, NULL);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
|
||||
stlink_exit_dfu_mode(sl);
|
||||
}
|
||||
if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
|
||||
stlink_exit_dfu_mode(sl);
|
||||
}
|
||||
|
||||
if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) {
|
||||
stlink_enter_swd_mode(sl);
|
||||
}
|
||||
|
||||
uint32_t chip_id = stlink_chip_id(sl);
|
||||
printf("Chip ID is %08x.\n", chip_id);
|
||||
uint32_t core_id = stlink_core_id(sl);
|
||||
|
||||
/* Fix chip_id for F4 */
|
||||
if (((chip_id & 0xFFF) == 0x411) && (core_id == CORE_M4_R0)) {
|
||||
printf("Fixing wrong chip_id for STM32F4 Rev A errata\n");
|
||||
chip_id = 0x413;
|
||||
}
|
||||
|
||||
printf("Chip ID is %08x, Core ID is %08x.\n", chip_id, core_id);
|
||||
|
||||
const struct chip_params* params = NULL;
|
||||
|
||||
|
@ -182,6 +204,9 @@ int main(int argc, char** argv) {
|
|||
|
||||
while(serve(sl, port) == 0);
|
||||
|
||||
/* Switch back to mass storage mode before closing. */
|
||||
stlink_run(sl);
|
||||
stlink_exit_debug_mode(sl);
|
||||
stlink_close(sl);
|
||||
|
||||
return 0;
|
||||
|
@ -578,7 +603,9 @@ int serve(stlink_t *sl, int port) {
|
|||
|
||||
printf("Listening at *:%d...\n", port);
|
||||
|
||||
(void) signal (SIGINT, ctrl_c);
|
||||
int client = accept(sock, NULL, NULL);
|
||||
signal (SIGINT, SIG_DFL);
|
||||
if(client < 0) {
|
||||
perror("accept");
|
||||
return 1;
|
||||
|
|
|
@ -80,12 +80,14 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "stlink-common.h"
|
||||
|
||||
#if CONFIG_USE_LIBSG
|
||||
// sgutils2 (apt-get install libsgutils2-dev)
|
||||
#include <scsi/sg_lib.h>
|
||||
#include <scsi/sg_pt.h>
|
||||
|
||||
#include "stlink-common.h"
|
||||
#include "stlink-sg.h"
|
||||
#endif
|
||||
|
||||
|
||||
// Suspends execution of the calling process for
|
||||
|
|
533
src/stlink-usb.c
533
src/stlink-usb.c
|
@ -1,4 +1,3 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -9,6 +8,8 @@
|
|||
#include "stlink-common.h"
|
||||
#include "stlink-usb.h"
|
||||
|
||||
enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80};
|
||||
|
||||
void _stlink_usb_close(stlink_t* sl) {
|
||||
struct stlink_libusb * const handle = sl->backend_data;
|
||||
// maybe we couldn't even get the usb device?
|
||||
|
@ -19,8 +20,9 @@ void _stlink_usb_close(stlink_t* sl) {
|
|||
if (handle->rep_trans != NULL)
|
||||
libusb_free_transfer(handle->rep_trans);
|
||||
|
||||
if (handle->usb_handle != NULL)
|
||||
if (handle->usb_handle != NULL) {
|
||||
libusb_close(handle->usb_handle);
|
||||
}
|
||||
|
||||
libusb_exit(handle->libusb_ctx);
|
||||
free(handle);
|
||||
|
@ -88,10 +90,11 @@ int submit_wait(struct stlink_libusb *slu, struct libusb_transfer * trans) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
ssize_t send_recv(struct stlink_libusb* handle,
|
||||
ssize_t send_recv(struct stlink_libusb* handle, int terminate,
|
||||
unsigned char* txbuf, size_t txsize,
|
||||
unsigned char* rxbuf, size_t rxsize) {
|
||||
/* note: txbuf and rxbuf can point to the same area */
|
||||
int res = 0;
|
||||
|
||||
libusb_fill_bulk_transfer(handle->req_trans, handle->usb_handle,
|
||||
handle->ep_req,
|
||||
|
@ -100,118 +103,146 @@ ssize_t send_recv(struct stlink_libusb* handle,
|
|||
0
|
||||
);
|
||||
|
||||
printf("submit_wait(req)\n");
|
||||
|
||||
if (submit_wait(handle, handle->req_trans)) return -1;
|
||||
|
||||
/* send_only */
|
||||
if (rxsize == 0) return 0;
|
||||
if (rxsize != 0) {
|
||||
|
||||
/* read the response */
|
||||
/* read the response */
|
||||
|
||||
libusb_fill_bulk_transfer(handle->rep_trans, handle->usb_handle,
|
||||
handle->ep_rep, rxbuf, rxsize, NULL, NULL, 0);
|
||||
libusb_fill_bulk_transfer(handle->rep_trans, handle->usb_handle,
|
||||
handle->ep_rep, rxbuf, rxsize, NULL, NULL, 0);
|
||||
|
||||
printf("submit_wait(rep)\n");
|
||||
|
||||
if (submit_wait(handle, handle->rep_trans)) return -1;
|
||||
if (submit_wait(handle, handle->rep_trans)) return -1;
|
||||
res = handle->rep_trans->actual_length;
|
||||
}
|
||||
if ((handle->protocoll == 1) && terminate) {
|
||||
/* Read the SG reply */
|
||||
unsigned char sg_buf[13];
|
||||
libusb_fill_bulk_transfer
|
||||
(handle->rep_trans, handle->usb_handle,
|
||||
handle->ep_rep, sg_buf, 13, NULL, NULL, 0);
|
||||
res = submit_wait(handle, handle->rep_trans);
|
||||
/* The STLink doesn't seem to evaluate the sequence number */
|
||||
handle->sg_transfer_idx++;
|
||||
if (res ) return -1;
|
||||
}
|
||||
|
||||
return handle->rep_trans->actual_length;
|
||||
}
|
||||
|
||||
static inline int send_only
|
||||
(struct stlink_libusb* handle, unsigned char* txbuf, size_t txsize) {
|
||||
return send_recv(handle, txbuf, txsize, NULL, 0);
|
||||
(struct stlink_libusb* handle, int terminate,
|
||||
unsigned char* txbuf, size_t txsize) {
|
||||
return send_recv(handle, terminate, txbuf, txsize, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
// KARL - fixme, common code! (or, one per backend)
|
||||
// candidate for common code...
|
||||
|
||||
|
||||
static int is_stlink_device(libusb_device * dev) {
|
||||
/* Search for a STLINK device, either any or teh one with the given PID
|
||||
* Return the protocoll version
|
||||
*/
|
||||
static int is_stlink_device(libusb_device * dev, uint16_t pid) {
|
||||
struct libusb_device_descriptor desc;
|
||||
int version;
|
||||
|
||||
if (libusb_get_device_descriptor(dev, &desc))
|
||||
return 0;
|
||||
|
||||
printf("device: 0x%04x, 0x%04x\n", desc.idVendor, desc.idProduct);
|
||||
|
||||
if (desc.idVendor != USB_ST_VID)
|
||||
return 0;
|
||||
|
||||
if (desc.idProduct != USB_STLINK_32L_PID)
|
||||
if ((desc.idProduct != USB_STLINK_32L_PID) &&
|
||||
(desc.idProduct != USB_STLINK_PID ))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
if(pid && (pid != desc.idProduct))
|
||||
return 0;
|
||||
if (desc.idProduct == USB_STLINK_PID )
|
||||
version = 1;
|
||||
else
|
||||
version = 2;
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
static int fill_command
|
||||
(stlink_t * sl, enum SCSI_Generic_Direction dir, uint32_t len) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
int i = 0;
|
||||
memset(cmd, 0, sizeof (sl->c_buf));
|
||||
if(slu->protocoll == 1) {
|
||||
cmd[i++] = 'U';
|
||||
cmd[i++] = 'S';
|
||||
cmd[i++] = 'B';
|
||||
cmd[i++] = 'C';
|
||||
write_uint32(&cmd[i], slu->sg_transfer_idx);
|
||||
write_uint32(&cmd[i + 4], len);
|
||||
i += 8;
|
||||
cmd[i++] = (dir == SG_DXFER_FROM_DEV)?0x80:0;
|
||||
cmd[i++] = 0; /* Logical unit */
|
||||
cmd[i++] = 0xa; /* Command length */
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void _stlink_usb_version(stlink_t *sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
uint32_t rep_len = 6;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
buf[0] = STLINK_GET_VERSION;
|
||||
buf[1] = 0x80;
|
||||
cmd[i++] = STLINK_GET_VERSION;
|
||||
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#if 1 /* DEBUG */
|
||||
{
|
||||
ssize_t i;
|
||||
for (i = 0; i < size; ++i) printf("%02x", buf[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
void _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char *cmd_buf = sl->c_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
|
||||
memset(cmd_buf, 0, STLINK_CMD_SIZE);
|
||||
cmd_buf[0] = STLINK_DEBUG_COMMAND;
|
||||
cmd_buf[1] = STLINK_DEBUG_WRITEMEM_32BIT;
|
||||
write_uint32(cmd_buf + 2, addr);
|
||||
write_uint16(cmd_buf + 6, len);
|
||||
send_only(slu, cmd_buf, STLINK_CMD_SIZE);
|
||||
|
||||
assert((len & 3) == 0);
|
||||
stlink_print_data(sl);
|
||||
send_only(slu, buf, len);
|
||||
int i = fill_command(sl, SG_DXFER_TO_DEV, len);
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_WRITEMEM_32BIT;
|
||||
write_uint32(&cmd[i], addr);
|
||||
write_uint16(&cmd[i + 4], len);
|
||||
send_only(slu, 0, cmd, slu->cmd_len);
|
||||
|
||||
send_only(slu, 1, data, len);
|
||||
}
|
||||
|
||||
void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char *cmd_buf = sl->c_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
|
||||
memset(cmd_buf, 0, STLINK_CMD_SIZE);
|
||||
cmd_buf[0] = STLINK_DEBUG_COMMAND;
|
||||
cmd_buf[1] = STLINK_DEBUG_WRITEMEM_8BIT;
|
||||
write_uint32(cmd_buf + 2, addr);
|
||||
write_uint16(cmd_buf + 6, len);
|
||||
send_only(slu, cmd_buf, STLINK_CMD_SIZE);
|
||||
|
||||
stlink_print_data(sl);
|
||||
send_only(slu, buf, len);
|
||||
int i = fill_command(sl, SG_DXFER_TO_DEV, 0);
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_WRITEMEM_8BIT;
|
||||
write_uint32(&cmd[i], addr);
|
||||
write_uint16(&cmd[i + 4], len);
|
||||
send_only(slu, 0, cmd, slu->cmd_len);
|
||||
send_only(slu, 1, data, len);
|
||||
}
|
||||
|
||||
|
||||
int _stlink_usb_current_mode(stlink_t * sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
ssize_t size;
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
buf[0] = STLINK_GET_CURRENT_MODE;
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
int rep_len = 2;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
cmd[i++] = STLINK_GET_CURRENT_MODE;
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return -1;
|
||||
|
@ -221,76 +252,71 @@ int _stlink_usb_current_mode(stlink_t * sl) {
|
|||
|
||||
void _stlink_usb_core_id(stlink_t * sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
ssize_t size;
|
||||
int rep_len = 4;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
buf[0] = STLINK_DEBUG_COMMAND;
|
||||
buf[1] = STLINK_DEBUG_READCOREID;
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_READCOREID;
|
||||
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sl->core_id = read_uint32(buf, 0);
|
||||
sl->core_id = read_uint32(data, 0);
|
||||
}
|
||||
|
||||
void _stlink_usb_status(stlink_t * sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
int rep_len = 2;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_GETSTATUS;
|
||||
|
||||
buf[0] = STLINK_DEBUG_COMMAND;
|
||||
buf[1] = STLINK_DEBUG_GETSTATUS;
|
||||
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* todo: stlink_core_stat */
|
||||
|
||||
// FIXME - decode into sl->core_stat
|
||||
#if 1 /* DEBUG */
|
||||
printf("status == 0x%x\n", buf[0]);
|
||||
#endif /* DEBUG */
|
||||
|
||||
}
|
||||
|
||||
void _stlink_usb_force_debug(stlink_t *sl) {
|
||||
struct stlink_libusb *slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
int rep_len = 2;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
|
||||
buf[0] = STLINK_DEBUG_COMMAND;
|
||||
buf[1] = STLINK_DEBUG_FORCEDEBUG;
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_FORCEDEBUG;
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _stlink_usb_enter_swd_mode(stlink_t * sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
const int rep_len = 0;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_ENTER;
|
||||
cmd[i++] = STLINK_DEBUG_ENTER_SWD;
|
||||
|
||||
buf[0] = STLINK_DEBUG_COMMAND;
|
||||
buf[1] = STLINK_SWD_ENTER;
|
||||
buf[2] = STLINK_DEBUG_ENTER_SWD;
|
||||
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
size = send_only(slu, 1, cmd, slu->cmd_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
|
@ -299,14 +325,14 @@ void _stlink_usb_enter_swd_mode(stlink_t * sl) {
|
|||
|
||||
void _stlink_usb_exit_dfu_mode(stlink_t* sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, 0);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
buf[0] = STLINK_DFU_COMMAND;
|
||||
buf[1] = STLINK_DFU_EXIT;
|
||||
cmd[i++] = STLINK_DFU_COMMAND;
|
||||
cmd[i++] = STLINK_DFU_EXIT;
|
||||
|
||||
size = send_only(slu, buf, 16);
|
||||
size = send_only(slu, 1, cmd, slu->cmd_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
|
@ -319,14 +345,16 @@ void _stlink_usb_exit_dfu_mode(stlink_t* sl) {
|
|||
*/
|
||||
void _stlink_usb_reset(stlink_t * sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
int rep_len = 2;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
buf[0] = STLINK_DEBUG_COMMAND;
|
||||
buf[1] = STLINK_DEBUG_RESETSYS;
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_RESETSYS;
|
||||
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
|
@ -336,14 +364,16 @@ void _stlink_usb_reset(stlink_t * sl) {
|
|||
|
||||
void _stlink_usb_step(stlink_t* sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
int rep_len = 2;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
buf[0] = STLINK_DEBUG_COMMAND;
|
||||
buf[1] = STLINK_DEBUG_STEPCORE;
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_STEPCORE;
|
||||
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
|
@ -356,31 +386,32 @@ void _stlink_usb_step(stlink_t* sl) {
|
|||
*/
|
||||
void _stlink_usb_run(stlink_t* sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
int rep_len = 2;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
buf[0] = STLINK_DEBUG_COMMAND;
|
||||
buf[1] = STLINK_DEBUG_RUNCORE;
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_RUNCORE;
|
||||
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _stlink_usb_exit_debug_mode(stlink_t *sl) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, 0);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
buf[0] = STLINK_DEBUG_COMMAND;
|
||||
buf[1] = STLINK_DEBUG_EXIT;
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_EXIT;
|
||||
|
||||
size = send_only(slu, buf, 16);
|
||||
size = send_only(slu, 1, cmd, slu->cmd_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_only\n");
|
||||
return;
|
||||
|
@ -389,22 +420,17 @@ void _stlink_usb_exit_debug_mode(stlink_t *sl) {
|
|||
|
||||
void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, len);
|
||||
|
||||
/* assume len < sizeof(sl->q_buf) */
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_READMEM_32BIT;
|
||||
write_uint32(&cmd[i], addr);
|
||||
write_uint16(&cmd[i + 4], len);
|
||||
|
||||
memset(buf, 0, sizeof (sl->q_buf));
|
||||
buf[0] = STLINK_DEBUG_COMMAND;
|
||||
buf[1] = STLINK_DEBUG_READMEM_32BIT;
|
||||
write_uint32(buf + 2, addr);
|
||||
|
||||
/* need to add +1 to len, otherwise get residue errors */
|
||||
len += 1;
|
||||
buf[6] = (uint8_t) len;
|
||||
buf[7] = (uint8_t) (len >> 8);
|
||||
|
||||
size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf));
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
|
@ -415,20 +441,17 @@ void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
|
|||
stlink_print_data(sl);
|
||||
}
|
||||
|
||||
|
||||
#if 1 /* stlinkv1 */
|
||||
|
||||
void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const cmd_buf = sl->c_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
ssize_t size;
|
||||
int i;
|
||||
uint32_t rep_len = 84;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(cmd_buf, 0, STLINK_CMD_SIZE);
|
||||
cmd_buf[0] = STLINK_DEBUG_COMMAND;
|
||||
cmd_buf[1] = STLINK_DEBUG_READALLREGS;
|
||||
size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 84);
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_READALLREGS;
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
|
@ -452,53 +475,19 @@ void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) {
|
|||
DD(sl, "rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80));
|
||||
}
|
||||
|
||||
#else /* stlinkv2 */
|
||||
|
||||
static void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const cmd_buf = sl->c_buf;
|
||||
ssize_t size;
|
||||
int i;
|
||||
|
||||
#define STLINK_JTAG_COMMAND 0xf2
|
||||
#define STLINK_JTAG_READALLREGS2 0x3a
|
||||
memset(cmd_buf, 0, STLINK_CMD_SIZE);
|
||||
cmd_buf[0] = STLINK_JTAG_COMMAND;
|
||||
cmd_buf[1] = STLINK_JTAG_READALLREGS2;
|
||||
size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 84);
|
||||
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sl->q_len = (size_t) size;
|
||||
|
||||
for(i=0; i<16; i++)
|
||||
regp->r[i]= read_uint32(sl->q_buf, i*4);
|
||||
|
||||
regp->xpsr = read_uint32(sl->q_buf, 64);
|
||||
regp->main_sp = read_uint32(sl->q_buf, 68);
|
||||
regp->process_sp = read_uint32(sl->q_buf, 72);
|
||||
regp->rw = read_uint32(sl->q_buf, 76);
|
||||
regp->rw2 = read_uint32(sl->q_buf, 80);
|
||||
}
|
||||
|
||||
#endif /* stlinkv1 */
|
||||
|
||||
void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char* const cmd_buf = sl->c_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
uint32_t r;
|
||||
uint32_t rep_len = 4;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(cmd_buf, 0, STLINK_CMD_SIZE);
|
||||
cmd_buf[0] = STLINK_DEBUG_COMMAND;
|
||||
cmd_buf[1] = STLINK_DEBUG_READREG;
|
||||
cmd_buf[2] = (uint8_t) r_idx;
|
||||
size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 4);
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_READREG;
|
||||
cmd[i++] = (uint8_t) r_idx;
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
|
@ -519,31 +508,29 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) {
|
|||
regp->process_sp = r;
|
||||
break;
|
||||
case 19:
|
||||
regp->rw = r; //XXX ?(primask, basemask etc.)
|
||||
regp->rw = r; /* XXX ?(primask, basemask etc.) */
|
||||
break;
|
||||
case 20:
|
||||
regp->rw2 = r; //XXX ?(primask, basemask etc.)
|
||||
regp->rw2 = r; /* XXX ?(primask, basemask etc.) */
|
||||
break;
|
||||
default:
|
||||
regp->r[r_idx] = r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 1 /* stlinkv1 */
|
||||
|
||||
void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char *cmd_buf = sl->c_buf;
|
||||
unsigned char* const data = sl->q_buf;
|
||||
unsigned char* const cmd = sl->c_buf;
|
||||
ssize_t size;
|
||||
uint32_t rep_len = 2;
|
||||
int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);
|
||||
|
||||
memset(cmd_buf, 0, STLINK_CMD_SIZE);
|
||||
cmd_buf[0] = STLINK_DEBUG_COMMAND;
|
||||
cmd_buf[1] = STLINK_DEBUG_WRITEREG;
|
||||
cmd_buf[2] = idx;
|
||||
write_uint32(cmd_buf + 3, reg);
|
||||
size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 2);
|
||||
cmd[i++] = STLINK_DEBUG_COMMAND;
|
||||
cmd[i++] = STLINK_DEBUG_WRITEREG;
|
||||
cmd[i++] = idx;
|
||||
write_uint32(&cmd[i], reg);
|
||||
size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
|
@ -552,32 +539,6 @@ void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) {
|
|||
stlink_print_data(sl);
|
||||
}
|
||||
|
||||
#else /* stlinkv2 */
|
||||
|
||||
void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) {
|
||||
struct stlink_libusb * const slu = sl->backend_data;
|
||||
unsigned char* const buf = sl->q_buf;
|
||||
unsigned char *cmd_buf = sl->c_buf;
|
||||
ssize_t size;
|
||||
|
||||
#define STLINK_JTAG_WRITEREG2 0x34
|
||||
memset(cmd_buf, 0, STLINK_CMD_SIZE);
|
||||
cmd_buf[0] = STLINK_JTAG_COMMAND;
|
||||
cmd_buf[1] = STLINK_JTAG_WRITEREG2;
|
||||
cmd_buf[2] = idx;
|
||||
write_uint32(cmd_buf + 3, reg);
|
||||
size = send_recv(slu, cmd_buf, STLINK_CMD_SIZE, buf, 2);
|
||||
if (size == -1) {
|
||||
printf("[!] send_recv\n");
|
||||
return;
|
||||
}
|
||||
sl->q_len = (size_t) size;
|
||||
stlink_print_data(sl);
|
||||
}
|
||||
|
||||
#endif /* stlinkv1 */
|
||||
|
||||
|
||||
stlink_backend_t _stlink_usb_backend = {
|
||||
_stlink_usb_close,
|
||||
_stlink_usb_exit_debug_mode,
|
||||
|
@ -601,37 +562,47 @@ stlink_backend_t _stlink_usb_backend = {
|
|||
};
|
||||
|
||||
|
||||
stlink_t* stlink_open_usb(const char *dev_name, const int verbose) {
|
||||
stlink_t* stlink_open_usb(const int verbose) {
|
||||
stlink_t* sl = NULL;
|
||||
struct stlink_libusb* slu = NULL;
|
||||
|
||||
/* unused */
|
||||
dev_name = dev_name;
|
||||
|
||||
sl = malloc(sizeof (stlink_t));
|
||||
slu = malloc(sizeof (struct stlink_libusb));
|
||||
if (sl == NULL) goto on_error;
|
||||
if (slu == NULL) goto on_error;
|
||||
|
||||
sl->verbose = verbose;
|
||||
|
||||
if (slu->libusb_ctx != NULL) {
|
||||
fprintf(stderr, "reopening with an existing context? undefined behaviour!\n");
|
||||
goto on_error;
|
||||
} else {
|
||||
if (libusb_init(&(slu->libusb_ctx))) {
|
||||
fprintf(stderr, "failed to init libusb context, wrong version of libraries?\n");
|
||||
goto on_error;
|
||||
}
|
||||
}
|
||||
|
||||
int error = -1;
|
||||
|
||||
libusb_device** devs = NULL;
|
||||
libusb_device* dev;
|
||||
ssize_t i;
|
||||
ssize_t count;
|
||||
int config;
|
||||
char *iSerial = NULL;
|
||||
|
||||
sl = malloc(sizeof (stlink_t));
|
||||
slu = malloc(sizeof (struct stlink_libusb));
|
||||
if (sl == NULL) goto on_error;
|
||||
if (slu == NULL) goto on_error;
|
||||
memset(sl, 0, sizeof (stlink_t));
|
||||
memset(slu, 0, sizeof (struct stlink_libusb));
|
||||
|
||||
sl->verbose = verbose;
|
||||
sl->backend = &_stlink_usb_backend;
|
||||
sl->backend_data = slu;
|
||||
|
||||
sl->core_stat = STLINK_CORE_STAT_UNKNOWN;
|
||||
|
||||
/* flash memory settings */
|
||||
sl->flash_base = STM32_FLASH_BASE;
|
||||
sl->flash_size = STM32_FLASH_SIZE;
|
||||
sl->flash_pgsz = STM32_FLASH_PGSZ;
|
||||
|
||||
/* system memory */
|
||||
sl->sys_base = STM32_SYSTEM_BASE;
|
||||
sl->sys_size = STM32_SYSTEM_SIZE;
|
||||
|
||||
/* sram memory settings */
|
||||
sl->sram_base = STM32_SRAM_BASE;
|
||||
sl->sram_size = STM32L_SRAM_SIZE;
|
||||
|
||||
if (libusb_init(&(slu->libusb_ctx))) {
|
||||
fprintf(stderr, "failed to init libusb context, wrong version of libraries?\n");
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
count = libusb_get_device_list(slu->libusb_ctx, &devs);
|
||||
if (count < 0) {
|
||||
|
@ -641,15 +612,48 @@ stlink_t* stlink_open_usb(const char *dev_name, const int verbose) {
|
|||
|
||||
for (i = 0; i < count; ++i) {
|
||||
dev = devs[i];
|
||||
if (is_stlink_device(dev)) break;
|
||||
slu->protocoll = is_stlink_device(dev, 0);
|
||||
if (slu->protocoll > 0) break;
|
||||
}
|
||||
if (i == count) return NULL;
|
||||
if (i == count) goto on_libusb_error;
|
||||
|
||||
if (libusb_open(dev, &(slu->usb_handle))) {
|
||||
printf("libusb_open()\n");
|
||||
goto on_libusb_error;
|
||||
}
|
||||
|
||||
if (iSerial) {
|
||||
unsigned char serial[256];
|
||||
struct libusb_device_descriptor desc;
|
||||
int r;
|
||||
|
||||
r = libusb_get_device_descriptor(dev, &desc);
|
||||
if (r<0) {
|
||||
printf("Can't get descriptor to match Iserial\n");
|
||||
goto on_libusb_error;
|
||||
}
|
||||
r = libusb_get_string_descriptor_ascii
|
||||
(slu->usb_handle, desc.iSerialNumber, serial, 256);
|
||||
if (r<0) {
|
||||
printf("Can't get Serialnumber to match Iserial\n");
|
||||
goto on_libusb_error;
|
||||
}
|
||||
if (strcmp((char*)serial, iSerial)) {
|
||||
printf("Mismatch in serial numbers, dev %s vs given %s\n",
|
||||
serial, iSerial);
|
||||
goto on_libusb_error;
|
||||
}
|
||||
}
|
||||
|
||||
if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) {
|
||||
int r;
|
||||
|
||||
r = libusb_detach_kernel_driver(slu->usb_handle, 0);
|
||||
if (r<0)
|
||||
printf("libusb_detach_kernel_driver(() error %s\n", strerror(-r));
|
||||
goto on_libusb_error;
|
||||
}
|
||||
|
||||
if (libusb_get_configuration(slu->usb_handle, &config)) {
|
||||
/* this may fail for a previous configured device */
|
||||
printf("libusb_get_configuration()\n");
|
||||
|
@ -685,15 +689,20 @@ stlink_t* stlink_open_usb(const char *dev_name, const int verbose) {
|
|||
slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
|
||||
slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
|
||||
|
||||
/* libusb_reset_device(slu->usb_handle); */
|
||||
slu->sg_transfer_idx = 0;
|
||||
slu->cmd_len = (slu->protocoll == 1)? STLINK_SG_SIZE: STLINK_CMD_SIZE;
|
||||
|
||||
/* success */
|
||||
if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
|
||||
printf("-- exit_dfu_mode\n");
|
||||
stlink_exit_dfu_mode(sl);
|
||||
}
|
||||
stlink_version(sl);
|
||||
error = 0;
|
||||
|
||||
on_libusb_error:
|
||||
if (devs != NULL) {
|
||||
libusb_free_device_list(devs, 1);
|
||||
fprintf(stderr, "freed libusb device list\n");
|
||||
}
|
||||
|
||||
if (error == -1) {
|
||||
|
@ -701,22 +710,6 @@ on_libusb_error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sl->backend = &_stlink_usb_backend;
|
||||
sl->backend_data = slu;
|
||||
|
||||
/* flash memory settings */
|
||||
sl->flash_base = STM32_FLASH_BASE;
|
||||
sl->flash_size = STM32_FLASH_SIZE;
|
||||
sl->flash_pgsz = STM32_FLASH_PGSZ;
|
||||
|
||||
/* system memory */
|
||||
sl->sys_base = STM32_SYSTEM_BASE;
|
||||
sl->sys_size = STM32_SYSTEM_SIZE;
|
||||
|
||||
/* sram memory settings */
|
||||
sl->sram_base = STM32_SRAM_BASE;
|
||||
sl->sram_size = STM32L_SRAM_SIZE;
|
||||
|
||||
/* success */
|
||||
return sl;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ extern "C" {
|
|||
#include <libusb-1.0/libusb.h>
|
||||
#include "stlink-common.h"
|
||||
|
||||
#define STLINK_SG_SIZE 31
|
||||
#define STLINK_CMD_SIZE 16
|
||||
|
||||
#if defined(CONFIG_USE_LIBUSB)
|
||||
|
@ -25,6 +26,9 @@ extern "C" {
|
|||
struct libusb_transfer* rep_trans;
|
||||
unsigned int ep_req;
|
||||
unsigned int ep_rep;
|
||||
int protocoll;
|
||||
unsigned int sg_transfer_idx;
|
||||
unsigned int cmd_len;
|
||||
};
|
||||
#else
|
||||
#error "it's all bad!"
|
||||
|
@ -32,7 +36,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
|
||||
stlink_t* stlink_open_usb(const char *dev_name, const int verbose);
|
||||
stlink_t* stlink_open_usb(const int verbose);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if CONFIG_USE_LIBSG
|
||||
#include <scsi/sg_lib.h>
|
||||
#include <scsi/sg_pt.h>
|
||||
#endif
|
||||
#include "stlink-common.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
|
|
@ -10,7 +10,7 @@ int main(int ac, char** av) {
|
|||
ac = ac;
|
||||
av = av;
|
||||
|
||||
sl = stlink_open_usb(NULL, 10);
|
||||
sl = stlink_open_usb(10);
|
||||
if (sl != NULL) {
|
||||
printf("-- version\n");
|
||||
stlink_version(sl);
|
||||
|
|
Ładowanie…
Reference in New Issue