bootloader: update to work with F4
This commit is contained in:
parent
40ee01ce67
commit
68955ddfec
41
bootloader.c
41
bootloader.c
@ -2,7 +2,7 @@
|
||||
* @file
|
||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @copyright SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @date 2017-2019
|
||||
* @date 2017-2020
|
||||
*/
|
||||
/* standard libraries */
|
||||
#include <stdint.h> // standard integer types
|
||||
@ -17,6 +17,11 @@
|
||||
#include "global.h" // board definitions
|
||||
#include "usb_dfu.h" // USB DFU utilities
|
||||
|
||||
/** symbol for beginning of the application
|
||||
* @note this symbol will be provided by the bootloader linker script
|
||||
*/
|
||||
extern char __application_beginning;
|
||||
|
||||
/** bootloader entry point */
|
||||
void main(void);
|
||||
void main(void)
|
||||
@ -31,38 +36,20 @@ void main(void)
|
||||
__dfu_magic[1] = 0;
|
||||
__dfu_magic[2] = 0;
|
||||
__dfu_magic[3] = 0;
|
||||
} else if (0 == (RCC_CSR & 0xfc000000)) { // no reset flag present -> this was a soft reset using scb_reset_core() after clearing the flags using RCC_CSR_RMVF, this was the legacy way to start the DFU mode
|
||||
dfu_force = true;
|
||||
} else { // check if the force DFU mode input is set
|
||||
// disable SWJ pin to use as GPIO
|
||||
#if (defined(DFU_FORCE_PIN) && defined(DFU_FORCE_VALUE))
|
||||
#if ((GPIO(B) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(4) == GPIO_PIN(DFU_FORCE_PIN)))
|
||||
// JNTRST pin is used as DFU pin
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function domain
|
||||
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_JNTRST, 0); // keep SWJ enable bit don't use JNTRST
|
||||
#elif ((GPIO(B) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(3) == GPIO_PIN(DFU_FORCE_PIN))) || ((GPIO(A) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(15) == GPIO_PIN(DFU_FORCE_PIN)))
|
||||
// JTAG but not SWD pin used as DFU pin
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function domain
|
||||
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, 0); // disable JTAG but keep SWD
|
||||
#elif ((GPIO(A) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(14) == GPIO_PIN(DFU_FORCE_PIN))) || ((GPIO(A) == GPIO_PORT(DFU_FORCE_PIN)) && (GPIO(13) == GPIO_PIN(DFU_FORCE_PIN)))
|
||||
// JTAG and SWD pin used as DFU pin
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function domain
|
||||
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_OFF, 0); // disable JTAG and SWD
|
||||
#endif // DFU_FORCE_PIN
|
||||
rcc_periph_clock_enable(GPIO_RCC(DFU_FORCE_PIN)); // enable clock for GPIO domain
|
||||
gpio_set_mode(GPIO_PORT(DFU_FORCE_PIN), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_PIN(DFU_FORCE_PIN)); // set GPIO to input
|
||||
// pull on the opposite of the expected value
|
||||
rcc_periph_clock_enable(GPIO_RCC(DFU_FORCE_PIN)); // enable clock for button
|
||||
#if (DFU_FORCE_VALUE == 1)
|
||||
gpio_clear(GPIO_PORT(DFU_FORCE_PIN), GPIO_PIN(DFU_FORCE_PIN)); // pull down to be able to detect when tied to high
|
||||
gpio_mode_setup(GPIO_PORT(DFU_FORCE_PIN), GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN(DFU_FORCE_PIN)); // set GPIO to input
|
||||
if (gpio_get(GPIO_PORT(DFU_FORCE_PIN), GPIO_PIN(DFU_FORCE_PIN))) { // check if output is set to the value to force DFU mode
|
||||
#else
|
||||
gpio_set(GPIO_PORT(DFU_FORCE_PIN), GPIO_PIN(DFU_FORCE_PIN)); // pull up to be able to detect when tied to low
|
||||
gpio_mode_setup(GPIO_PORT(DFU_FORCE_PIN), GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN(DFU_FORCE_PIN)); // set GPIO to input
|
||||
if (0 == gpio_get(GPIO_PORT(DFU_FORCE_PIN), GPIO_PIN(DFU_FORCE_PIN))) { // check if output is set to the value to force DFU mode
|
||||
#endif // DFU_FORCE_VALUE
|
||||
dfu_force = true; // DFU mode forced
|
||||
}
|
||||
#endif // defined(DFU_FORCE_PIN)
|
||||
rcc_periph_clock_disable(RCC_AFIO); // disable alternate function domain to put it back to default
|
||||
rcc_periph_reset_pulse(GPIO_RST(DFU_FORCE_PIN)); // reset pin GPIO domain
|
||||
rcc_periph_clock_disable(GPIO_RCC(DFU_FORCE_PIN)); // disable pin GPIO domain
|
||||
}
|
||||
@ -71,24 +58,20 @@ void main(void)
|
||||
/* the application starts with the vector table
|
||||
* the first entry in the vector table is the initial stack pointer (SP) address
|
||||
* the stack will be placed in RAM
|
||||
* on STM32F1xx SRAM begins at 0x2000 0000, and on STM32F103xx there is up to 96 KB of RAM (0x18000).
|
||||
* since the stack grown "downwards" it should start at the end of the RAM: max 0x2001 8000
|
||||
* on STM32F4 SRAM begins at 0x2000 0000, and on STM32F4xx there is up to 384 KiB of RAM (0x60000).
|
||||
* since the stack grown "downwards" it should start at the end of the RAM: max 0x2006 0000
|
||||
* if the SP is not in this range (e.g. flash has been erased) there is no valid application
|
||||
* the second entry in the vector table is the reset address, corresponding to the application start
|
||||
*/
|
||||
volatile uint32_t* application = (uint32_t*)&__application_beginning; // get the value of the application address symbol (use a register instead on the stack since the stack pointer will be changed)
|
||||
if (!dfu_force && (((*application) & 0xFFFE0000) == 0x20000000)) { // application at address seems valid
|
||||
if (!dfu_force && (((*application) & 0xFFF80000) == 0x20000000)) { // application at address seems valid
|
||||
SCB_VTOR = (volatile uint32_t)(application); // set vector table to application vector table (store at the beginning of the application)
|
||||
__asm__ volatile ("MSR msp,%0" : :"r"(*application)); // set stack pointer to address provided in the beginning of the application (loaded into a register first)
|
||||
(*(void(**)(void))((uint32_t)application + 4))(); // start application (by jumping to the reset function which address is stored as second entry of the vector table)
|
||||
}
|
||||
|
||||
rcc_clock_setup_in_hse_8mhz_out_72mhz(); // start main clock
|
||||
board_setup(); // setup board to control LED
|
||||
led_on(); // indicate bootloader started
|
||||
#if defined(BUSVOODOO)
|
||||
led_toggle(); // switch from blue to red LED
|
||||
#endif
|
||||
usb_dfu_setup(); // setup USB DFU for firmware upload
|
||||
usb_dfu_start(); // run DFU mode
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user