From b85f4319eee38792748a9d26e70142574658de43 Mon Sep 17 00:00:00 2001 From: Hristo Mitrev Date: Tue, 9 Jan 2024 20:41:38 +0200 Subject: [PATCH] stlink: support stlink v2 isol variant --- src/platforms/stlink/Makefile.inc | 4 ++++ src/platforms/stlink/platform.c | 19 +++++++++++++++++++ src/platforms/stlink/platform.h | 21 +++++++++++++++++++++ src/platforms/stlink/stlink_common.c | 19 +++++++++++++++---- 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/platforms/stlink/Makefile.inc b/src/platforms/stlink/Makefile.inc index e8e25ebbe3b..895787556ca 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 e9ba1ae2128..60815077130 100644 --- a/src/platforms/stlink/platform.c +++ b/src/platforms/stlink/platform.c @@ -52,6 +52,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: @@ -69,7 +82,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..67e5f5fd662 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 @@ -77,7 +82,22 @@ extern bool debug_bmp; #define SWD_CR GPIO_CRH(SWDIO_PORT) #define SWD_CR_MULT (1U << ((14U - 8U) << 2U)) +#define SWDIODIR_ODR GPIO_ODR(GPIOA) + #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 { \ + SWDIODIR_ODR |= (GPIO1); \ + } while (0) +#define SWDIO_MODE_DRIVE() \ + do { \ + SWDIODIR_ODR &= ~(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 +112,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)