diff --git a/src/platforms/stlink/Makefile.inc b/src/platforms/stlink/Makefile.inc index d10878a4e62..2442af08c4b 100644 --- a/src/platforms/stlink/Makefile.inc +++ b/src/platforms/stlink/Makefile.inc @@ -39,6 +39,10 @@ ifeq ($(STLINK_FORCE_CLONE), 1) CFLAGS += -DSTLINK_FORCE_CLONE=1 endif +ifeq ($(STLINK_V2_ISOL), 1) +CFLAGS += -DSTLINK_V2_ISOL=1 +endif + VPATH += platforms/common/stm32 SRC += \ diff --git a/src/platforms/stlink/platform.c b/src/platforms/stlink/platform.c index 191a1fbbae6..243941c5507 100644 --- a/src/platforms/stlink/platform.c +++ b/src/platforms/stlink/platform.c @@ -51,6 +51,19 @@ void platform_init(void) #ifdef BLUEPILL led_idle_run = GPIO13; nrst_pin = NRST_PIN_V1; +#elif defined(STLINK_V2_ISOL) + led_idle_run = GPIO9; + nrst_pin = NRST_PIN_V2; + /* PB12 is SWDIO_IN */ + gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO12); + /* PA4 is used to set SWDCLK floating when set to 1 */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO4); + gpio_clear(GPIOA, GPIO4); + /* PA1 is used to set SWDIO floating and MUXED to SWDIO_IN when set to 1 */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO1); +#elif defined(STLINK_FORCE_CLONE) + led_idle_run = GPIO9; + nrst_pin = NRST_PIN_CLONE; #else switch (rev) { case 0: @@ -68,7 +81,13 @@ void platform_init(void) } #endif /* Setup GPIO ports */ +#ifdef STLINK_V2_ISOL + /* In case of ISOL variant, this pin is never set to high impedance */ + gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, TMS_PIN); +#else + /* In all other variants, this pin is initialized as high impedance */ gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_INPUT_FLOAT, TMS_PIN); +#endif gpio_set_mode(TCK_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, TCK_PIN); gpio_set_mode(TDI_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, TDI_PIN); diff --git a/src/platforms/stlink/platform.h b/src/platforms/stlink/platform.h index fa56aa105e7..34ba4533e37 100644 --- a/src/platforms/stlink/platform.h +++ b/src/platforms/stlink/platform.h @@ -53,6 +53,11 @@ extern bool debug_bmp; #define SWDIO_PIN TMS_PIN #define SWCLK_PIN TCK_PIN +#ifdef STLINK_V2_ISOL +#define SWDIO_IN_PORT GPIOB +#define SWDIO_IN_PIN GPIO12 +#endif + #define NRST_PORT GPIOB #define NRST_PIN_V1 GPIO1 #define NRST_PIN_V2 GPIO0 @@ -78,6 +83,19 @@ extern bool debug_bmp; #define SWD_CR_MULT (1U << ((14U - 8U) << 2U)) #define TMS_SET_MODE() gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, TMS_PIN); + +#ifdef STLINK_V2_ISOL +/* The ISOL variant floats SWDIO with GPIO A1 */ +#define SWDIO_MODE_FLOAT() \ + do { \ + gpio_set(GPIOA, GPIO1); \ + } while (0) +#define SWDIO_MODE_DRIVE() \ + do { \ + gpio_clear(GPIOA, GPIO1); \ + } while (0) +#else +/* All other variants just set SWDIO_PIN to floating */ #define SWDIO_MODE_FLOAT() \ do { \ uint32_t cr = SWD_CR; \ @@ -92,6 +110,7 @@ extern bool debug_bmp; cr |= (0x1U * SWD_CR_MULT); \ SWD_CR = cr; \ } while (0) +#endif #define UART_PIN_SETUP() \ do { \ gpio_set_mode(USBUSART_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, USBUSART_TX_PIN); \ diff --git a/src/platforms/stlink/stlink_common.c b/src/platforms/stlink/stlink_common.c index 3f638c21cbe..0e9df492796 100644 --- a/src/platforms/stlink/stlink_common.c +++ b/src/platforms/stlink/stlink_common.c @@ -25,6 +25,8 @@ #include "platform.h" +/* If we force CLONE or V2_ISOL variant, we don't need to read GPIO levels */ +#if !(defined(STLINK_FORCE_CLONE) || defined(STLINK_V2_ISOL)) static bool stlink_stable_read(const uint32_t gpio_port, const uint16_t gpio) { bool result = false; @@ -32,6 +34,7 @@ static bool stlink_stable_read(const uint32_t gpio_port, const uint16_t gpio) result = gpio_get(gpio_port, gpio); return result; } +#endif /* Return 0 for ST-Link v1, 1 for ST-Link v2 and 2 for ST-Link v2.1 */ uint32_t detect_rev(void) @@ -45,6 +48,17 @@ uint32_t detect_rev(void) rcc_periph_reset_pulse(RST_USB); rcc_periph_clock_enable(RCC_AFIO); rcc_periph_clock_enable(RCC_CRC); + +#if defined(STLINK_FORCE_CLONE) + /* PA12 is USB D+ pin */ + gpio_clear(GPIOA, GPIO12); + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12); + /* Override detection to use clone pinmap (i.e. PB6 as nRST). */ + return 0x101; +#elif defined(STLINK_V2_ISOL) + /* Override detection to stlink v2 isol*/ + return 0x103; +#else /* * First, get the board revision by pulling PC13/14 up then reading them. * This gives us the following table of values for these pins: @@ -89,16 +103,13 @@ uint32_t detect_rev(void) gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8); } - /* Override detection to use clone pinmap (i.e. PB6 as nRST). */ -#if defined(STLINK_FORCE_CLONE) - revision = 0x101; -#endif /* Clean up after ourself on boards that aren't identified as ST-Link v2.1's */ if ((revision & 0xff) < 2U) { gpio_clear(GPIOA, GPIO12); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12); } return revision; +#endif } void platform_request_boot(void)