Skip to content

Commit

Permalink
Adding support for ST-Link v2 clones
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean THOMAS committed Nov 30, 2017
1 parent d52d781 commit ae3a418
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 27 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
PLATFORM = bluepill

OBJS := src/dirtyjtag.o src/jtag.o src/usb.o src/delay.o src/cmd.o

PREFIX ?= arm-none-eabi
Expand All @@ -14,6 +16,7 @@ CFLAGS = -g
CFLAGS += -Wall -Wextra -Werror
CFLAGS += -fno-common -ffunction-sections -fdata-sections
CFLAGS += -std=gnu11
CFLAGS += -DPLATFORM='HW_$(PLATFORM)'

CPPFLAGS = -MD -g
CPPFLAGS += -Wall -Wundef
Expand Down
133 changes: 106 additions & 27 deletions src/jtag.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,104 @@
#include "delay.h"
#include "jtag.h"

#define JTAG_PORT GPIOA
#define JTAG_TDI GPIO0
#define JTAG_TDO GPIO1
#define JTAG_TCK GPIO2
#define JTAG_TMS GPIO3
#define JTAG_TRST GPIO4
#define JTAG_SRST GPIO5
#define HW_stlinkv2 0
#define HW_bluepill 1

#if PLATFORM == HW_stlinkv2 /* Chinese ST-LinkV2 clone */

#define JTAG_PORT_TDI GPIOB
#define JTAG_PIN_TDI GPIO8

#define JTAG_PORT_TDO GPIOB
#define JTAG_PIN_TDO GPIO14

#define JTAG_PORT_TCK GPIOA
#define JTAG_PIN_TCK GPIO5

#define JTAG_PORT_TMS GPIOB
#define JTAG_PIN_TMS GPIO6

#else /* Blue Pill platform (default) */

#define JTAG_PORT_TDI GPIOA
#define JTAG_PIN_TDI GPIO0

#define JTAG_PORT_TDO GPIOA
#define JTAG_PIN_TDO GPIO1

#define JTAG_PORT_TCK GPIOA
#define JTAG_PIN_TCK GPIO2

#define JTAG_PORT_TMS GPIOA
#define JTAG_PIN_TMS GPIO3

#define JTAG_PORT_TRST GPIOA
#define JTAG_PIN_TRST GPIO4

#define JTAG_PORT_SRST GPIOA
#define JTAG_PIN_SRST GPIO5

#endif

#if !defined(JTAG_PORT_TDI) || \
!defined(JTAG_PORT_TDO) || \
!defined(JTAG_PORT_TMS) || \
!defined(JTAG_PORT_TCK)
#error "Not enough pins defined for proper JTAG operation"
#endif

static uint32_t period = 1;

void jtag_init(void) {
/* GPIO configuration */
gpio_set_mode(JTAG_PORT,
gpio_set_mode(JTAG_PORT_TCK,
GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL,
JTAG_TCK | JTAG_TDI | JTAG_TMS | JTAG_SRST | JTAG_TRST);
gpio_set_mode(JTAG_PORT,
JTAG_PIN_TCK);
gpio_set_mode(JTAG_PORT_TDI,
GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL,
JTAG_PIN_TDI);
gpio_set_mode(JTAG_PORT_TMS,
GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL,
JTAG_PIN_TMS);
gpio_set_mode(JTAG_PORT_TDO,
GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN,
JTAG_TDO);
JTAG_PIN_TDO);
#ifdef JTAG_PORT_SRST
gpio_set_mode(JTAG_PORT_SRST,
GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL,
JTAG_PIN_SRST);
#endif
#ifdef JTAG_PORT_TRST
gpio_set_mode(JTAG_PORT_TRST,
GPIO_MODE_OUTPUT_50_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL,
JTAG_PIN_TRST);
#endif
#if PLATFORM == HW_stlinkv2
/* Put weird STLinkV2 clone pull pins in high impedance state */
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT,
GPIO5 | GPIO7 | GPIO9 | GPIO10 | GPIO12);
#endif

/* Set default pin state */
gpio_clear(JTAG_PORT, JTAG_TCK | JTAG_TMS | JTAG_TDI);
gpio_set(JTAG_PORT, JTAG_TRST | JTAG_SRST);
gpio_clear(JTAG_PORT_TCK, JTAG_PIN_TCK);
gpio_clear(JTAG_PORT_TMS, JTAG_PIN_TMS);
gpio_clear(JTAG_PORT_TDI, JTAG_PIN_TDI);
#ifdef JTAG_PORT_TRST
gpio_set(JTAG_PORT_TRST, JTAG_PIN_TRST);
#endif
#ifdef JTAG_PORT_SRST
gpio_set(JTAG_PORT_SRST, JTAG_PIN_SRST);
#endif

/* Set pull-down on TDO */
gpio_clear(JTAG_PORT, JTAG_TDO);
gpio_clear(JTAG_PORT_TDO, JTAG_PIN_TDO);
}

void jtag_set_frequency(uint32_t frequency) {
Expand All @@ -43,56 +114,64 @@ void jtag_set_frequency(uint32_t frequency) {
void jtag_clock(void) {
delay_us(period/2);

gpio_set(JTAG_PORT, JTAG_TCK);
gpio_set(JTAG_PORT_TCK, JTAG_PIN_TCK);

delay_us(period);

gpio_clear(JTAG_PORT, JTAG_TCK);
gpio_clear(JTAG_PORT_TCK, JTAG_PIN_TCK);
delay_us(period/2);
}

void jtag_set_tck(uint8_t value) {
if (value) {
gpio_set(JTAG_PORT, JTAG_TCK);
gpio_set(JTAG_PORT_TCK, JTAG_PIN_TCK);
} else {
gpio_clear(JTAG_PORT, JTAG_TCK);
gpio_clear(JTAG_PORT_TCK, JTAG_PIN_TCK);
}
}

void jtag_set_tms(uint8_t value) {
if (value) {
gpio_set(JTAG_PORT, JTAG_TMS);
gpio_set(JTAG_PORT_TMS, JTAG_PIN_TMS);
} else {
gpio_clear(JTAG_PORT, JTAG_TMS);
gpio_clear(JTAG_PORT_TMS, JTAG_PIN_TMS);
}
}

void jtag_set_tdi(uint8_t value) {
if (value) {
gpio_set(JTAG_PORT, JTAG_TDI);
gpio_set(JTAG_PORT_TDI, JTAG_PIN_TDI);
} else {
gpio_clear(JTAG_PORT, JTAG_TDI);
gpio_clear(JTAG_PORT_TDI, JTAG_PIN_TDI);
}
}

uint8_t jtag_get_tdo(void) {
return gpio_get(JTAG_PORT, JTAG_TDO) ? 1 : 0;
return gpio_get(JTAG_PORT_TDO, JTAG_PIN_TDO) ? 1 : 0;
}

void jtag_set_trst(uint8_t value) {
#ifdef JTAG_PORT_TRST
if (value) {
gpio_set(JTAG_PORT, JTAG_TRST);
gpio_set(JTAG_PORT_TRST, JTAG_PIN_TRST);
} else {
gpio_clear(JTAG_PORT, JTAG_TRST);
gpio_clear(JTAG_PORT_TRST, JTAG_PIN_TRST);
}
#else
(void)value;
#endif
}

void jtag_set_srst(uint8_t value) {
#ifdef JTAG_PORT_SRST
if (value) {
gpio_set(JTAG_PORT, JTAG_SRST);
gpio_set(JTAG_PORT_SRST, JTAG_PIN_SRST);
} else {
gpio_clear(JTAG_PORT, JTAG_SRST);
gpio_clear(JTAG_PORT_SRST, JTAG_PIN_SRST);
}
#else
(void)value;
#endif
}

void jtag_transfer(uint16_t length, const uint8_t *in, uint8_t *out) {
Expand Down

0 comments on commit ae3a418

Please sign in to comment.