aboutsummaryrefslogtreecommitdiff
path: root/src/platforms/stlink
diff options
context:
space:
mode:
Diffstat (limited to 'src/platforms/stlink')
-rw-r--r--src/platforms/stlink/Makefile.inc13
-rw-r--r--src/platforms/stlink/dfu_upgrade.c127
-rw-r--r--src/platforms/stlink/platform.h2
-rw-r--r--src/platforms/stlink/usbdfu.c33
4 files changed, 161 insertions, 14 deletions
diff --git a/src/platforms/stlink/Makefile.inc b/src/platforms/stlink/Makefile.inc
index 1f46588..5cfe726 100644
--- a/src/platforms/stlink/Makefile.inc
+++ b/src/platforms/stlink/Makefile.inc
@@ -18,7 +18,7 @@ SRC += cdcacm.c \
platform.c \
usbuart.c \
-all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex
+all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex dfu_upgrade.bin dfu_upgrade.hex
blackmagic.bin: blackmagic
$(OBJCOPY) -O binary $^ $@
@@ -32,6 +32,15 @@ blackmagic_dfu.bin: blackmagic_dfu
blackmagic_dfu.hex: blackmagic_dfu
$(OBJCOPY) -O ihex $^ $@
+dfu_upgrade: dfu_upgrade.o dfucore.o dfu_f1.o
+ $(CC) $^ -o $@ $(LDFLAGS)
+
+dfu_upgrade.bin: dfu_upgrade
+ $(OBJCOPY) -O binary $^ $@
+
+dfu_upgrade.hex: dfu_upgrade
+ $(OBJCOPY) -O ihex $^ $@
+
host_clean:
- -rm blackmagic.bin blackmagic_dfu blackmagic_dfu.bin blackmagic_dfu.hex
+ -rm blackmagic.bin blackmagic_dfu blackmagic_dfu.bin blackmagic_dfu.hex dfu_upgrade dfu_upgrade.bin dfu_upgrade.hex
diff --git a/src/platforms/stlink/dfu_upgrade.c b/src/platforms/stlink/dfu_upgrade.c
new file mode 100644
index 0000000..2c7c1ad
--- /dev/null
+++ b/src/platforms/stlink/dfu_upgrade.c
@@ -0,0 +1,127 @@
+/*
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2013 Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <libopencm3/cm3/systick.h>
+#include <libopencm3/stm32/rcc.h>
+#include <libopencm3/stm32/gpio.h>
+#include <libopencm3/cm3/scb.h>
+
+#include "usbdfu.h"
+uint32_t app_address = 0x08000000;
+
+static uint8_t rev;
+static uint16_t led_idle_run;
+static uint32_t led2_state = 0;
+
+void dfu_detach(void)
+{
+ /* Disconnect USB cable by resetting USB Device
+ and pulling USB_DP low*/
+ rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1ENR_USBEN);
+ rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1ENR_USBEN);
+ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN);
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
+ gpio_clear(GPIOA, GPIO12);
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12);
+ /* Pull PB0 (T_NRST) low
+ */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
+ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_OPENDRAIN, GPIO0);
+ gpio_clear(GPIOB, GPIO0);
+ SCB_VTOR = 0;
+ scb_reset_core();
+}
+
+void stlink_set_rev(void)
+{
+ int i;
+
+ /* First, get Board revision by pulling PC13/14 up. Read
+ * 11 for ST-Link V1, e.g. on VL Discovery, tag as rev 0
+ * 10 for ST-Link V2, e.g. on F4 Discovery, tag as rev 1
+ */
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
+ gpio_set_mode(GPIOC, GPIO_MODE_INPUT,
+ GPIO_CNF_INPUT_PULL_UPDOWN, GPIO14 | GPIO13);
+ gpio_set(GPIOC, GPIO14 | GPIO13);
+ for (i = 0; i < 100; i++)
+ rev = (~(gpio_get(GPIOC, GPIO14 | GPIO13)) >> 13) & 3;
+
+ switch (rev) {
+ case 0:
+ led_idle_run = GPIO8;
+ break;
+ default:
+ led_idle_run = GPIO9;
+ }
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, led_idle_run);
+}
+
+int main(void)
+{
+
+ rcc_clock_setup_in_hse_8mhz_out_72mhz();
+
+ stlink_set_rev();
+
+ systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
+ systick_set_reload(900000);
+
+ dfu_protect(UPD_MODE);
+
+ /* 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_peripheral_reset(&RCC_APB1RSTR, RCC_APB1ENR_USBEN);
+ rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1ENR_USBEN);
+ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN);
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
+ gpio_clear(GPIOA, GPIO12);
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12);
+
+ systick_interrupt_enable();
+ systick_counter_enable();
+
+ dfu_init(&stm32f103_usb_driver, UPD_MODE);
+
+ dfu_main();
+}
+
+void sys_tick_handler(void)
+{
+ if (rev == 0) {
+ gpio_toggle(GPIOA, led_idle_run);
+ } else {
+ if (led2_state & 1) {
+ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, led_idle_run);
+ gpio_set(GPIOA, led_idle_run);
+ } else {
+ gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
+ GPIO_CNF_INPUT_ANALOG, led_idle_run);
+ }
+ led2_state++;
+ }
+}
diff --git a/src/platforms/stlink/platform.h b/src/platforms/stlink/platform.h
index a9e405b..ffe9fbf 100644
--- a/src/platforms/stlink/platform.h
+++ b/src/platforms/stlink/platform.h
@@ -36,8 +36,10 @@
#define CDCACM_PACKET_SIZE 64
#define BOARD_IDENT "Black Magic Probe (STLINK), (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define BOARD_IDENT_DFU "Black Magic (Upgrade) for STLink/Discovery, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
+#define BOARD_IDENT_UPD "Black Magic (DFU Upgrade) for STLink/Discovery, (Firmware 1.5" VERSION_SUFFIX ", build " BUILDDATE ")"
#define DFU_IDENT "Black Magic Firmware Upgrade (STLINK)"
#define DFU_IFACE_STRING "@Internal Flash /0x08000000/8*001Ka,56*001Kg"
+#define UPD_IFACE_STRING "@Internal Flash /0x08000000/8*001Kg"
extern usbd_device *usbdev;
#define CDCACM_GDB_ENDPOINT 1
diff --git a/src/platforms/stlink/usbdfu.c b/src/platforms/stlink/usbdfu.c
index c14fd5a..1a40e64 100644
--- a/src/platforms/stlink/usbdfu.c
+++ b/src/platforms/stlink/usbdfu.c
@@ -29,24 +29,31 @@ static uint8_t rev;
static uint16_t led_idle_run;
static uint32_t led2_state = 0;
+uint32_t app_address = 0x08002000;
+
static int stlink_test_nrst(void)
{
/* Test if JRST/NRST is pulled down*/
- int i;
uint16_t nrst;
uint16_t pin;
+ uint32_t systick_value;
+
+ systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);
+ systick_set_reload(0xffffff); /* no underflow for about 16.7 seconds*/
+ systick_counter_enable();
+ /* systick ist now running with 1 MHz, systick counts down */
/* First, get Board revision by pulling PC13/14 up. Read
* 11 for ST-Link V1, e.g. on VL Discovery, tag as rev 0
* 10 for ST-Link V2, e.g. on F4 Discovery, tag as rev 1
*/
- for (i = 0; i < 0x200; i++) {
- rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
- gpio_set_mode(GPIOC, GPIO_MODE_INPUT,
- GPIO_CNF_INPUT_PULL_UPDOWN, GPIO14 | GPIO13);
- gpio_set(GPIOC, GPIO14 | GPIO13);
- rev = (~(gpio_get(GPIOC, GPIO14 | GPIO13)) >> 13) & 3;
- }
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
+ gpio_set_mode(GPIOC, GPIO_MODE_INPUT,
+ GPIO_CNF_INPUT_PULL_UPDOWN, GPIO14 | GPIO13);
+ gpio_set(GPIOC, GPIO14 | GPIO13);
+ systick_value = systick_get_value();
+ while (systick_get_value() > (systick_value - 1000)); /* Wait 1 msec*/
+ rev = (~(gpio_get(GPIOC, GPIO14 | GPIO13)) >> 13) & 3;
switch (rev) {
case 0:
pin = GPIO1;
@@ -62,8 +69,10 @@ static int stlink_test_nrst(void)
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN, pin);
gpio_set(GPIOB, pin);
- for (i = 0; i < 100; i++)
- nrst = gpio_get(GPIOB, pin);
+ systick_value = systick_get_value();
+ while (systick_get_value() > (systick_value - 20000)); /* Wait 20 msec*/
+ nrst = gpio_get(GPIOB, pin);
+ systick_counter_disable();
return (nrst) ? 1 : 0;
}
@@ -92,7 +101,7 @@ int main(void)
if(((GPIOA_CRL & 0x40) == 0x40) && stlink_test_nrst())
dfu_jump_app_if_valid();
- dfu_protect_enable();
+ dfu_protect(DFU_MODE);
rcc_clock_setup_in_hse_8mhz_out_72mhz();
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
@@ -113,7 +122,7 @@ int main(void)
systick_interrupt_enable();
systick_counter_enable();
- dfu_init(&stm32f103_usb_driver);
+ dfu_init(&stm32f103_usb_driver, DFU_MODE);
dfu_main();
}