diff --git a/src/platforms/stlink/Bootloader_Upgrade b/src/platforms/stlink/Bootloader_Upgrade new file mode 100644 index 0000000..f9c93f0 --- /dev/null +++ b/src/platforms/stlink/Bootloader_Upgrade @@ -0,0 +1,22 @@ +Bootloader Upgrade on Stlink +============================ + +Beside accessing the SWD pins direct like explained on +https://embdev.net/articles/STM_Discovery_as_Black_Magic_Probe +an updated bootloader can also be programmed via DFU. This requires three +steps: +1. Prepare bootloader update +Normal BMP has to be replaced by the upgrade programm: + dfu-util -s 0x08002000:leave -D dfu_upgrade.bin +Wait until Dual color led flashes red, indicating DFU is active for the +bootloader. + +2. Flash new bootloader + dfu-util -s 0x08000000 -D blackmagic_dfu.bin +Wait until Dual color led flashes green, indicating bootloader is active. + +If not, unplug USB, keep black reset button pressed, replug USB. +Wait until Dual color led flashes green. + +3. Flash BMP + dfu-util -s 0x08002000:leave:force -D blackmagic.bin diff --git a/src/platforms/stlink/Flashsize_F103 b/src/platforms/stlink/Flashsize_F103 index d4ece0f..c6b55a2 100644 --- a/src/platforms/stlink/Flashsize_F103 +++ b/src/platforms/stlink/Flashsize_F103 @@ -24,16 +24,30 @@ Ignoring the chip marking and using an F103C8 blindly as a F103Cb is done already with few problems on many china boards (e.g. blue pill). Probably this second approach will work for many of the older STLinks. -Use at your own risk! +dfu-util cares for the size and refuses to programm above the announced size: + > dfu-util -S E4D078EA -s 0x08002000:leave -D blackmagic.bin + dfu-util 0.9 + ... + dfu-util: Last page at 0x0801093f is not writeable -With DFU upload available in the bootloader, you can verify by uploading the -binary from flash and comparing it against the binary downloaded. -- Download new BMP binary (if not already done) - dfu-util -s 0x08002000:leave:force -D blackmagic.bin -- Get length of binary +Flash above the announced size with recent bootloader/BMP: +========================================================== +script/stm32_mem.py does not care for the announced size: + > ../scripts/stm32_mem.py blackmagic.bin + ... + USB Device Firmware Upgrade - Host Utility -- version 1.2 + ... + Programming memory at 0x08010800 + All operations complete! + +Get length of binary > ls -l blackmagic.bin - -rwxr-xr-x 1 bon users 57372 15. Apr 14:17 blackmagic.bin -- Upload binary from flash - > dfu-util -s 0x08002000:leave:force:57372 -U blackmagic.bin.1 -- Compare + -rwxr-xr-x 1 bon users 59712 21. Sep 22:47 blackmagic.bin +Actual file size may differ! + +Upload binary from flash with the exact size + > dfu-util -s 0x08002000:leave:force:59712 -U blackmagic.bin.1 + +Compare > diff blackmagic.bin* +No differences should get reported! diff --git a/src/platforms/stlink/Makefile.inc b/src/platforms/stlink/Makefile.inc index d7edcf4..874695f 100644 --- a/src/platforms/stlink/Makefile.inc +++ b/src/platforms/stlink/Makefile.inc @@ -20,14 +20,15 @@ SRC += cdcacm.c \ serialno.c \ timing.c \ timing_stm32.c \ + stlink_common.c \ all: blackmagic.bin blackmagic_dfu.bin blackmagic_dfu.hex dfu_upgrade.bin dfu_upgrade.hex -blackmagic_dfu: usbdfu.o dfucore.o dfu_f1.o +blackmagic_dfu: usbdfu.o dfucore.o dfu_f1.o stlink_common.o @echo " LD $@" $(Q)$(CC) $^ -o $@ $(LDFLAGS_BOOT) -dfu_upgrade: dfu_upgrade.o dfucore.o dfu_f1.o +dfu_upgrade: dfu_upgrade.o dfucore.o dfu_f1.o stlink_common.o @echo " LD $@" $(Q)$(CC) $^ -o $@ $(LDFLAGS) diff --git a/src/platforms/stlink/dfu_upgrade.c b/src/platforms/stlink/dfu_upgrade.c index f5fc503..804144a 100644 --- a/src/platforms/stlink/dfu_upgrade.c +++ b/src/platforms/stlink/dfu_upgrade.c @@ -24,84 +24,40 @@ #include #include "usbdfu.h" -uint32_t app_address = 0x08000000; +#include "general.h" +#include "platform.h" -static uint8_t rev; -static uint16_t led_idle_run; +uint32_t app_address = 0x08000000; +static uint16_t led_upgrade; static uint32_t led2_state = 0; +extern uint32_t _stack; +static uint32_t rev; void dfu_detach(void) { - /* Disconnect USB cable by resetting USB Device - and pulling USB_DP low*/ - 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); - /* Pull PB0 (T_NRST) low - */ - rcc_periph_clock_enable(RCC_GPIOB); - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_OPENDRAIN, GPIO0); - gpio_clear(GPIOB, GPIO0); - SCB_VTOR = 0; + platform_request_boot(); 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_periph_clock_enable(RCC_GPIOC); - 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) { - + rev = detect_rev(); rcc_clock_setup_in_hse_8mhz_out_72mhz(); - - stlink_set_rev(); + if (rev == 0) + led_upgrade = GPIO8; + else + led_upgrade = GPIO9; systick_set_clocksource(STK_CSR_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_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); - systick_interrupt_enable(); systick_counter_enable(); + if (rev > 1) /* Reconnect USB */ + gpio_set(GPIOA, GPIO15); dfu_init(&stm32f103_usb_driver, UPD_MODE); dfu_main(); @@ -114,15 +70,15 @@ void dfu_event(void) void sys_tick_handler(void) { if (rev == 0) { - gpio_toggle(GPIOA, led_idle_run); + gpio_toggle(GPIOA, led_upgrade); } 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); + GPIO_CNF_OUTPUT_PUSHPULL, led_upgrade); + gpio_set(GPIOA, led_upgrade); } else { gpio_set_mode(GPIOA, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_ANALOG, led_idle_run); + GPIO_CNF_INPUT_ANALOG, led_upgrade); } led2_state++; } diff --git a/src/platforms/stlink/platform.c b/src/platforms/stlink/platform.c index dcc1493..5177b1c 100644 --- a/src/platforms/stlink/platform.c +++ b/src/platforms/stlink/platform.c @@ -34,56 +34,26 @@ #include uint8_t running_status; -volatile uint32_t timeout_counter; uint16_t led_idle_run; -/* Pins PC[14:13] are used to detect hardware revision. Read - * 11 for STLink V1 e.g. on VL Discovery, tag as hwversion 0 - * 10 for STLink V2 e.g. on F4 Discovery, tag as hwversion 1 - */ +uint16_t srst_pin; +static uint32_t rev; + int platform_hwversion(void) { - static int hwversion = -1; - int i; - if (hwversion == -1) { - gpio_set_mode(GPIOC, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_PULL_UPDOWN, GPIO14 | GPIO13); - gpio_set(GPIOC, GPIO14 | GPIO13); - for (i = 0; i<10; i++) - hwversion = ~(gpio_get(GPIOC, GPIO14 | GPIO13) >> 13) & 3; - switch (hwversion) - { - case 0: - led_idle_run = GPIO8; - break; - default: - led_idle_run = GPIO9; - } - } - return hwversion; + return rev; } void platform_init(void) { + rev = detect_rev(); rcc_clock_setup_in_hse_8mhz_out_72mhz(); - - /* 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_GPIOC); - rcc_periph_clock_enable(RCC_AFIO); - rcc_periph_clock_enable(RCC_CRC); - - /* On Rev 1 unconditionally activate MCO on PORTA8 with HSE - * platform_hwversion() also needed to initialize led_idle_run! - */ - if (platform_hwversion() == 1) - { - RCC_CFGR &= ~(0xf << 24); - RCC_CFGR |= (RCC_CFGR_MCO_HSECLK << 24); - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, - GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8); + if (rev == 0) { + led_idle_run = GPIO8; + srst_pin = SRST_PIN_V1; + } else { + led_idle_run = GPIO9; + srst_pin = SRST_PIN_V2; } /* Setup GPIO ports */ gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, @@ -92,8 +62,6 @@ void platform_init(void) GPIO_CNF_OUTPUT_PUSHPULL, TCK_PIN); gpio_set_mode(TDI_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, TDI_PIN); - uint16_t srst_pin = platform_hwversion() == 0 ? - SRST_PIN_V1 : SRST_PIN_V2; gpio_set(SRST_PORT, srst_pin); gpio_set_mode(SRST_PORT, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, srst_pin); @@ -106,51 +74,26 @@ void platform_init(void) SCB_VTOR = (uint32_t)&vector_table; platform_timing_init(); + if (rev > 1) /* Reconnect USB */ + gpio_set(GPIOA, GPIO15); cdcacm_init(); usbuart_init(); } void platform_srst_set_val(bool assert) { - uint16_t pin; - pin = platform_hwversion() == 0 ? SRST_PIN_V1 : SRST_PIN_V2; if (assert) - gpio_clear(SRST_PORT, pin); + gpio_clear(SRST_PORT, srst_pin); else - gpio_set(SRST_PORT, pin); + gpio_set(SRST_PORT, srst_pin); } bool platform_srst_get_val() { - uint16_t pin; - pin = platform_hwversion() == 0 ? SRST_PIN_V1 : SRST_PIN_V2; - return gpio_get(SRST_PORT, pin) == 0; + return gpio_get(SRST_PORT, srst_pin) == 0; } const char *platform_target_voltage(void) { return "unknown"; } - -void platform_request_boot(void) -{ - /* Disconnect USB cable by resetting USB Device and pulling USB_DP low*/ - 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); - - /* Assert bootloader pin */ - uint32_t crl = GPIOA_CRL; - rcc_periph_clock_enable(RCC_GPIOA); - /* Enable Pull on GPIOA1. We don't rely on the external pin - * really pulled, but only on the value of the CNF register - * changed from the reset value - */ - crl &= 0xffffff0f; - crl |= 0x80; - GPIOA_CRL = crl; -} - diff --git a/src/platforms/stlink/platform.h b/src/platforms/stlink/platform.h index f74a1af..26ee153 100644 --- a/src/platforms/stlink/platform.h +++ b/src/platforms/stlink/platform.h @@ -110,6 +110,8 @@ extern uint16_t led_idle_run; #define SET_IDLE_STATE(state) {gpio_set_val(LED_PORT, led_idle_run, state);} #define SET_ERROR_STATE(x) +extern uint32_t detect_rev(void); + /* Use newlib provided integer only stdio functions */ #define sscanf siscanf #define sprintf siprintf diff --git a/src/platforms/stlink/stlink_common.c b/src/platforms/stlink/stlink_common.c new file mode 100644 index 0000000..487563d --- /dev/null +++ b/src/platforms/stlink/stlink_common.c @@ -0,0 +1,102 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2017 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 + +/* return 0 for stlink V1, 1 for stlink V2 and 2 for stlink V2.1 */ +uint32_t detect_rev(void) +{ + uint32_t rev; + int res; + + while (RCC_CFGR & 0xf) /* Switch back to HSI. */ + RCC_CFGR &= ~3; + rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_GPIOB); + rcc_periph_clock_enable(RCC_GPIOC); + rcc_periph_clock_enable(RCC_USB); + rcc_periph_reset_pulse(RST_USB); + rcc_periph_clock_enable(RCC_AFIO); + rcc_periph_clock_enable(RCC_CRC); + /* First, get Board revision by pulling PC13/14 up. Read + * 11 for ST-Link V1, e.g. on VL Discovery, tag as rev 0 + * 00 for ST-Link V2, e.g. on F4 Discovery, tag as rev 1 + * 01 for ST-Link V2, else, tag as rev 1 + */ + gpio_set_mode(GPIOC, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_PULL_UPDOWN, GPIO14 | GPIO13); + gpio_set(GPIOC, GPIO14 | GPIO13); + for (int i = 0; i < 100; i ++) + res = gpio_get(GPIOC, GPIO13); + if (res) + rev = 0; + else { + /* Check for V2.1 boards. + * PA15/TDI is USE_RENUM, pulled with 10 k to U5V on V2.1, + * Otherwise unconnected. Enable pull low. If still high. + * it is V2.1.*/ + rcc_periph_clock_enable(RCC_AFIO); + AFIO_MAPR |= 0x02000000; /* Release from TDI.*/ + gpio_set_mode(GPIOA, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_PULL_UPDOWN, GPIO15); + gpio_clear(GPIOA, GPIO15); + for (int i = 0; i < 100; i++) + res = gpio_get(GPIOA, GPIO15); + if (res) { + rev = 2; + /* Pull PWR_ENn low.*/ + gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_OPENDRAIN, GPIO15); + gpio_clear(GPIOB, GPIO15); + /* Pull USB_RENUM low!*/ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_OPENDRAIN, GPIO15); + gpio_clear(GPIOA, GPIO15); + } else + /* Catch F4 Disco board with both resistors fitted.*/ + rev = 1; + /* On Rev > 0 unconditionally activate MCO on PORTA8 with HSE! */ + RCC_CFGR &= ~(0xf << 24); + RCC_CFGR |= (RCC_CFGR_MCO_HSECLK << 24); + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO8); + } + if (rev < 2) { + gpio_clear(GPIOA, GPIO12); + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_OPENDRAIN, GPIO12); + } + return rev; +} + +void platform_request_boot(void) +{ + uint32_t crl = GPIOA_CRL; + /* Assert bootloader marker. + * Enable Pull on GPIOA1. We don't rely on the external pin + * really pulled, but only on the value of the CNF register + * changed from the reset value + */ + crl &= 0xffffff0f; + crl |= 0x80; + GPIOA_CRL = crl; + SCB_VTOR = 0; +} diff --git a/src/platforms/stlink/usbdfu.c b/src/platforms/stlink/usbdfu.c index f5c30a9..fca3bf6 100644 --- a/src/platforms/stlink/usbdfu.c +++ b/src/platforms/stlink/usbdfu.c @@ -24,108 +24,57 @@ #include #include "usbdfu.h" +#include "general.h" +#include "platform.h" -static uint8_t rev; -static uint16_t led_idle_run; +static uint32_t rev; +static uint16_t led_bootloader; +static uint16_t pin_nrst; static uint32_t led2_state = 0; uint32_t app_address = 0x08002000; -static int stlink_test_nrst(void) +static bool stlink_test_nrst(void) { - /* Test if JRST/NRST is pulled down*/ uint16_t nrst; - uint16_t pin; - uint32_t systick_value; - - systick_set_clocksource(STK_CSR_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 - */ - rcc_periph_clock_enable(RCC_GPIOC); - 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; - led_idle_run = GPIO8; - break; - default: - pin = GPIO0; - led_idle_run = GPIO9; - } - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, led_idle_run); - rcc_periph_clock_enable(RCC_GPIOB); gpio_set_mode(GPIOB, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_PULL_UPDOWN, pin | GPIO15); - if (gpio_get(GPIOB, GPIO15)) { - /* ST890 is active low */ - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); - gpio_clear(GPIOB, GPIO15); - } - gpio_set(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; + GPIO_CNF_INPUT_PULL_UPDOWN, pin_nrst); + gpio_set(GPIOB, pin_nrst); + for (int i = 0; i < 10000; i++) + nrst = gpio_get(GPIOB, pin_nrst); + return (nrst) ? true : false; } void dfu_detach(void) { - /* Disconnect USB cable by resetting USB Device - and pulling USB_DP low*/ - 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); scb_reset_system(); } int main(void) { - /* Check the force bootloader pin*/ - rcc_periph_clock_enable(RCC_GPIOA); - /* Check value of GPIOA1 configuration. This pin is unconnected on - * STLink V1 and V2. If we have a value other than the reset value (0x4), - * we have a warm start and request Bootloader entry - */ + rev = detect_rev(); + if (rev == 0) { + led_bootloader = GPIO8; + pin_nrst = GPIO1; + } else { + led_bootloader = GPIO9; + pin_nrst = GPIO0; + } + if(((GPIOA_CRL & 0x40) == 0x40) && stlink_test_nrst()) dfu_jump_app_if_valid(); - dfu_protect(DFU_MODE); rcc_clock_setup_in_hse_8mhz_out_72mhz(); 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); systick_interrupt_enable(); systick_counter_enable(); + if (rev > 1) + gpio_set(GPIOA, GPIO15); dfu_init(&stm32f103_usb_driver, DFU_MODE); dfu_main(); @@ -138,16 +87,16 @@ void dfu_event(void) void sys_tick_handler(void) { if (rev == 0) { - gpio_toggle(GPIOA, led_idle_run); + gpio_toggle(GPIOA, led_bootloader); } else { if (led2_state & 1) { gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, - GPIO_CNF_OUTPUT_PUSHPULL, led_idle_run); + GPIO_CNF_OUTPUT_PUSHPULL, led_bootloader); + gpio_clear(GPIOA, led_bootloader); } else { gpio_set_mode(GPIOA, GPIO_MODE_INPUT, - GPIO_CNF_INPUT_ANALOG, led_idle_run); + GPIO_CNF_INPUT_ANALOG, led_bootloader); } led2_state++; } } -