diff --git a/src/platforms/swlink/Makefile.inc b/src/platforms/swlink/Makefile.inc
index aeee95a..0287d1d 100644
--- a/src/platforms/swlink/Makefile.inc
+++ b/src/platforms/swlink/Makefile.inc
@@ -26,6 +26,7 @@ SRC += cdcacm.c \
serialno.c \
timing.c \
timing_stm32.c \
+ platform_common.c \
all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
diff --git a/src/platforms/swlink/Readme b/src/platforms/swlink/Readme
index b4b3c2c..b6a442e 100644
--- a/src/platforms/swlink/Readme
+++ b/src/platforms/swlink/Readme
@@ -1,10 +1,30 @@
-Blackmagic for the STM8S Discovery Board
-========================================
+Blackmagic for STM8S Discovery and STM32F103 Minimum System Development Board
+=============================================================================
+
+* External connections:
+
+Function PIN STM8S-DISCO BLUPILL
+JTMS/SWDIO PA13 CN5/5 P2/2
+TTCK/SWCLK PA14 CN5/4 P2/3
+JTDI PA15 CN5/6 P4/11 (38)
+JTDO PB3 CN5/3 P4/10 (39)
+SRST PB4 CN5/8 P4/9 (40)
+
+UART1_TX PB6 CN7/4 P4/7 (42)
+UART1_RX PB7 CN7/2 P4/6 (43)
+
+References:
+https://www.st.com/resource/en/user_manual/cd00250600.pdf
+Blue Pill:
+https://jeelabs.org/img/2016/STM32F103C8T6-DEV-BOARD-SCH.pdf (first number)
+https://wiki.stm32duino.com/images/a/ae/Bluepillpinout.gif (second number)
+
+* STM8S Discovery
The board is a ST-Link V1 Board, but with access to JTAG pins accessible
on CN5. This allows easy reprogramming and reuse of the JTAG header.
Programmatical it seems indistinguishable from a e.g. STM32VL
-Discovery. So here avariant that uses CN5 for JTAG/SWD_TRACESWO and CN7 for
+Discovery. So here a variant that uses CN5 for JTAG/SWD and CN7 for
UART.
Force Bootloader entry is done with shorting CN7 Pin3/4 so PB6 read low while
@@ -13,3 +33,17 @@ pulled up momentary by PB6.
Reuse SWIM Pins for Uart (USART1)
RX: CN7 Pin2 ->SWIM_IN (PB7)/USART1_RX / SWIM_IN(PB9)
TX: CN7 Pin4 -> SWIM_RST_IN(PB6)/USART1_TX
+
+* STM32F103 Minimum System Development Board (aka Blue Pill)
+
+This board has the SWD pins of the onboard F103 accessible on one side.
+Reuse these pins. There are also jumpers for BOOT0 and BOOT1(PB2). Reuse
+Boot1 as "Force Bootloader entry" jumpered high when connecting to USB. Boot1
+has 100 k Ohm between MCU and header pin and can not be used as SRST.
+
+All other port pins are have header access with headers not yet soldered.
+JTAG TDO: PB3
+JTAG TDI: PA15
+SWD SWO: PA10 (use Uart pin as on normal STLINK)
+
+Distinguish boards by checking the SWIM_IN connection PB9/PB10
diff --git a/src/platforms/swlink/platform.c b/src/platforms/swlink/platform.c
index 9115085..3aa5477 100644
--- a/src/platforms/swlink/platform.c
+++ b/src/platforms/swlink/platform.c
@@ -18,8 +18,9 @@
* along with this program. If not, see .
*/
-/* This file implements the platform specific functions for the ST-Link
- * implementation.
+/* This file implements the platform specific functions for ST-Link
+ * on the STM8S discovery and STM32F103 Minimum System Development Board, also
+ * known as bluepill.
*/
#include "general.h"
@@ -34,6 +35,13 @@
#include
#include
+static uint8_t rev;
+
+int platform_hwversion(void)
+{
+ return rev;
+}
+
void platform_init(void)
{
uint32_t data;
@@ -44,10 +52,8 @@ void platform_init(void)
#endif
rcc_clock_setup_in_hse_8mhz_out_72mhz();
+ rev = detect_rev();
/* Enable peripherals */
- rcc_periph_clock_enable(RCC_USB);
- rcc_periph_clock_enable(RCC_GPIOA);
- rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_AFIO);
rcc_periph_clock_enable(RCC_CRC);
@@ -67,6 +73,14 @@ void platform_init(void)
gpio_set_mode(TDO_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOAT, TDO_PIN);
+ if (rev == 1) {
+ /* Enable MCO Out on PA8*/
+ RCC_CFGR &= ~(0xf << 24);
+ RCC_CFGR |= (RCC_CFGR_MCO_HSE << 24);
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
+ GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8);
+ }
+
gpio_set(NRST_PORT,NRST_PIN);
gpio_set_mode(NRST_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN, NRST_PIN);
diff --git a/src/platforms/swlink/platform.h b/src/platforms/swlink/platform.h
index 436dd24..e7dbe0a 100644
--- a/src/platforms/swlink/platform.h
+++ b/src/platforms/swlink/platform.h
@@ -3,6 +3,7 @@
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin
+ * Copyright (C) 2018 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.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
@@ -29,11 +30,11 @@
#include "timing_stm32.h"
#include "version.h"
-#define BOARD_IDENT "Black Magic Probe (SWLINK), (Firmware " FIRMWARE_VERSION ")"
-#define BOARD_IDENT_DFU "Black Magic (Upgrade), STM8S Discovery, (Firmware " FIRMWARE_VERSION ")"
-#define BOARD_IDENT_UPD "Black Magic (DFU Upgrade), STM8S Discovery, (Firmware " FIRMWARE_VERSION ")"
-#define DFU_IDENT "Black Magic Firmware Upgrade (SWLINK)"
-#define UPD_IFACE_STRING "@Internal Flash /0x08000000/8*001Kg"
+#define BOARD_IDENT "Black Magic Probe (SWLINK), (Firmware " FIRMWARE_VERSION ")"
+#define BOARD_IDENT_DFU "Black Magic (Upgrade), SWLINK, (Firmware " FIRMWARE_VERSION ")"
+#define BOARD_IDENT_UPD "Black Magic (DFU Upgrade), SWLINK, (Firmware " FIRMWARE_VERSION ")"
+#define DFU_IDENT "Black Magic Firmware Upgrade (SWLINK)"
+#define UPD_IFACE_STRING "@Internal Flash /0x08000000/8*001Kg"
/* Hardware definitions... */
#define TMS_PORT GPIOA
@@ -128,10 +129,7 @@ int usbuart_debug_write(const char *buf, size_t len);
#define SET_IDLE_STATE(state) {gpio_set_val(LED_PORT, LED_IDLE_RUN, state);}
#define SET_ERROR_STATE(x)
-static inline int platform_hwversion(void)
-{
- return 0;
-}
+extern uint8_t detect_rev(void);
/* Use newlib provided integer only stdio functions */
#define sscanf siscanf
diff --git a/src/platforms/swlink/platform_common.c b/src/platforms/swlink/platform_common.c
new file mode 100644
index 0000000..b1a3ad3
--- /dev/null
+++ b/src/platforms/swlink/platform_common.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2018 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.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 3 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 .
+ */
+
+#include
+#include
+#include
+
+uint8_t detect_rev()
+{
+ /* Test connectivity between PB9 and PB10 needed for
+ * original ST software to implement SWIM.
+ *
+ * Return 0 for Stlink on STM8S Disco and 1 for Bluepill
+ */
+ uint8_t rev = 0;
+ /* Enable Peripherals used by both debugger and DFU.*/
+ rcc_periph_clock_enable(RCC_GPIOA);
+ rcc_periph_clock_enable(RCC_GPIOB);
+ rcc_periph_clock_enable(RCC_USB);
+ gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
+ GPIO_CNF_INPUT_PULL_UPDOWN, GPIO9);
+ gpio_set(GPIOB, GPIO9);
+ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO10);
+ while (!gpio_get(GPIOB, GPIO10))
+ gpio_set(GPIOB, GPIO10);
+ while (gpio_get(GPIOB, GPIO10))
+ gpio_clear(GPIOB, GPIO10);
+ /* Read PB9 as soon as we read PB10 low.*/
+ if (gpio_get(GPIOB, GPIO9))
+ rev = 1;
+ /* Release PB9/10 */
+ gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
+ GPIO_CNF_INPUT_FLOAT, GPIO9 | GPIO10);
+ gpio_set(GPIOB, GPIO9);
+ switch (rev) {
+ case 0:
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO8);
+ break;
+ case 1:
+ rcc_periph_clock_enable(RCC_GPIOC);
+ gpio_set(GPIOC, GPIO13); /* LED on Blupill is active low!*/
+ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
+ break;
+ }
+ /* Disconnect USB after reset:
+ * Pull USB_DP low. Device will reconnect automatically
+ * when USB is set up later, as Pull-Up is hard wired*/
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12);
+ gpio_clear(GPIOA, GPIO12);
+ rcc_periph_reset_pulse(RST_USB);
+ rcc_periph_clock_enable(RCC_USB);
+
+ return rev;
+}
+
diff --git a/src/platforms/swlink/usbdfu.c b/src/platforms/swlink/usbdfu.c
index daf73f3..46ee39d 100644
--- a/src/platforms/swlink/usbdfu.c
+++ b/src/platforms/swlink/usbdfu.c
@@ -65,21 +65,6 @@ int main(void)
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
systick_set_reload(900000);
- /* Handle USB disconnect/connect */
- /* Just in case: Disconnect USB cable by resetting USB Device
- * and pulling USB_DP low
- * Device will reconnect automatically as Pull-Up is hard wired*/
- rcc_periph_reset_pulse(RST_USB);
- rcc_periph_clock_enable(RCC_USB);
- rcc_periph_clock_enable(RCC_GPIOA);
- gpio_clear(GPIOA, GPIO12);
- gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
- GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12);
-
- /* Handle LED*/
- gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
- GPIO_CNF_OUTPUT_PUSHPULL, GPIO8);
-
systick_interrupt_enable();
systick_counter_enable();