Starting bootloader from software on STM32F427 to use the USB port in DFU
Hello, I am trying to start the bootloader on a STM32F427 to program the MCU via USB port in DFU mode. I am not new to this topic because I wrote some programs for STM32F072 where I can successfully start the bootloader and take externally control of the MCU via serial port (there I don't need to program the boards via USB). In that products my software calls correctly the bootloader that works without any problem.
On this new design there is a bigger STM32F427; this time I need to program the MCU via the USB port and not via an UART. Here is the problem:
- If I start the bootloader using hardware signals (BOOT0 and RESET), all works as it should do: using STM32CubeProgrammer I can take control both via an UART or via the USB port.
- If I start the bootloader by software, STM32CubeProgrammer can take control only via the UART: the USB port doesn't start in DFU mode so the programmer doesn't find it.
After many attemps, to have a clean situation I finally put the bootloader call as the very first instruction in the main(). Despite this, I always have the same result: the bootloader starts but programmer works correctly via the UART and it doesn't see at all the USB port because it doesn't start in DFU mode.
This is the code I use to launch the bootloader (remember, after several tests now I call it as the first instruction in main() ). The code of this functions is derived from the many examples about starting bootloader, and (with the proper address) it is the same I use on smaller STM32F072.
/*
JumpToBootloader()
*/
void JumpToBootloader(void) {
void (*SysMemBootJump)(void);
/**
* Step: Set system memory address.
*
* For STM32L051, system memory is on 0x1FF00000
* For STM32F051, system memory is on 0x1FFFEC00
* For STM32F070xB, system memory is on 0x1FFFC800
* For STM32F072, system memory is on 0x1FFFC800
* For STM32F4xx, system memory is on 0x1FFF0000
*/
volatile uint32_t addr = 0x1FFF0000;
/**
* Step: Disable RCC, set it to default (after reset) settings
* Internal clock, no PLL, etc.
*/
HAL_RCC_DeInit();
HAL_DeInit();
/**
* Step: Disable systick timer and reset it to default values
*/
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/**
* Step: Disable all interrupts
*/
__disable_irq();
/* ARM Cortex-M Programming Guide to Memory Barrier Instructions.*/
__DSB();
/**
* Step: Remap system memory to address 0x0000 0000 in address space
* For each family registers may be different.
* Check reference manual for each family.
*
*/
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); //Call HAL macro to do this for you
/* Remap is bot visible at once. Execute some unrelated command! */
__DSB();
__ISB();
/**
* Step: Set jump memory location for system memory
* Use address with 4 bytes offset which specifies jump location where program starts
*/
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
/**
* Step: Set main stack pointer.
* This step must be done last otherwise local variables in this function
* don't have proper value since stack pointer is located on different position
*
* Set direct address location which specifies stack pointer in SRAM location
*/
__set_MSP(*(uint32_t *)addr);
/**
* Step: Actually call our function to jump to set location
* This will start system memory execution
*/
SysMemBootJump();
}
Can anyone help me to understand why after this the USB port doesn't start in DFU mode (but the UART works)? And why the USB port starts in DFU mode if I instead launch the bootloader by hardware?
Thank you very much.
