rcc_periph_clock_enable(RCC_GPIO(DFU_FORCE_PORT));// enable clock for GPIO domain
gpio_set_mode(GPIO(DFU_FORCE_PORT),GPIO_MODE_INPUT,GPIO_CNF_INPUT_PULL_UPDOWN,GPIO(DFU_FORCE_PIN));// set GPIO to input
// pull on the opposite of the expected value
if(DFU_FORCE_VALUE){
gpio_clear(GPIO(DFU_FORCE_PORT),GPIO(DFU_FORCE_PIN));// pull down to be able to detect when tied to high
}else{
gpio_set(GPIO(DFU_FORCE_PORT),GPIO(DFU_FORCE_PIN));// pull up to be able to detect when tied to low
}
if((!DFU_FORCE_VALUE&&0==gpio_get(GPIO(DFU_FORCE_PORT),GPIO(DFU_FORCE_PIN)))||(DFU_FORCE_VALUE&&0!=gpio_get(GPIO(DFU_FORCE_PORT),GPIO(DFU_FORCE_PIN)))){// check if output is set to the value to force DFU mode
volatileuint32_t*application=&__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
SCB_VTOR=(volatileuint32_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))(application+1))();// start application (by jumping to the reset function which address is stored as second entry of the vector table)