2025-09-17 2:55 PM - last edited on 2025-09-17 4:05 PM by Andrew Neil
Hi all,
I am a newer STM32 programmer, and I have been working on the STM32H745 Discovery board for the last few months. Something that I would like to do is be able to switch into USB DFU Mode within a UI that I have made for this board. I took inspiration from this post and changed the address to the appropriate one for the STM32H745. I would like to prerequisite that the USB port is initially configured as a VCP/CDC device. Here is the code that I have:
void (*SysMemBootJump) (void);
void USB_BootloaderInit()
{
volatile uint32_t addr = 0x1FFF9800; //from AN2606
__disable_irq();
// Reset USB OTG_FS
// Disable caches
SCB_DisableICache();
SCB_DisableDCache();
// Remap vector table
HAL_RCC_DeInit(); //Reset the system clock
SysTick->CTRL = 0; //Reset the SysTick Timer
SysTick->LOAD = 0;
SysTick->VAL = 0;
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4))); //Point the PC to the System Memory reset vector
__set_MSP(*(uint32_t *)addr); //Set the Main Stack Pointer
SysMemBootJump(); //Run our virtual function defined above that sets the PC
while(1);
}
Now, to test this code, I am simply calling it at the very beginning of main as such:
int main(void)
{
/* USER CODE BEGIN 1 */
USB_BootloaderInit();
/* USER CODE END 1 */
/* USER CODE BEGIN Boot_Mode_Sequence_0 */
int32_t timeout;
/* USER CODE END Boot_Mode_Sequence_0 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* USER CODE BEGIN Boot_Mode_Sequence_1 */
/* Wait until CPU2 boots and enters in stop mode or timeout*/
timeout = 0xFFFF;
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
if ( timeout < 0 )
{
Error_Handler();
}
But, when I get on STM32Cube Programmer, I do not see the device. I have tried using the debugger, but I think I am running into different issues because of the dual core nature of this. I would get errors from random things. The one that particularly stumped me is this line:
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4))); //Point the PC to the System Memory reset vector
would consistently trigger a hard fault error (IMPRECISSER)
I have looked around the forum posts that exist and I do not think I have found something quite like my issue.
Thank you for your time!
2025-09-17 3:12 PM
Here is code for jumping to the bootloader that works. Note the line that says __enable_irq.
How to jump to system bootloader from application ... - STMicroelectronics Community
Don't jump from within an interrupt.
Don't disable caches that aren't enabled.
Ensure the M4 core isn't booting, or has code that won't interfere with the bootloader.
2025-09-18 8:12 AM
Thank you for your response!
I think the key thing I was missing that you pointed out was disabling things that were never enabled. The program counter is now going to 0x1FF0CD4C, which, from my understanding, is the bootloader.
However, I still cannot see the device under the DFU tab of STM32Prog. Do you have any other advice?
The bootloader is v9.1, and Nothing is connected to the board (I do not expect the PB15 thing to be an issue). Does PB15 need to be set in order for it to boot?
Thanks!
2025-09-18 8:39 AM
Did you enable interrupts? Post your updated code.
2025-09-18 9:09 AM
The function is now this:
0
void USB_BootloaderInit()
{
volatile uint32_t BootAddr = 0x1FF09800;
uint32_t i=0;
void (*SysMemBootJump)(void);
/* Disable all interrupts */
__disable_irq();
MX_USB_DEVICE_DeInit();
/* Disable Systick timer */
SysTick->CTRL = 0;
/* Set the clock to the default state */
HAL_RCC_DeInit();
for (i = 0; i < sizeof(NVIC->ICER) / sizeof(NVIC->ICER[0]); i++)
{
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
__enable_irq();
SysMemBootJump = (void (*)(void)) (*((uint32_t *) ((BootAddr + 4))));
__set_MSP(*(uint32_t *)BootAddr);
SysMemBootJump();
while(1);
}
and I am simply calling it at the very beginning of main:
int main(void)
{
/* USER CODE BEGIN 1 */
USB_BootloaderInit(); //go into bootloader init
/* USER CODE END 1 */
/* USER CODE BEGIN Boot_Mode_Sequence_0 */
/* USER CODE END Boot_Mode_Sequence_0 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
2025-09-18 9:43 AM
I forgot that I was trying the DeInit before I posted this reply. Please ignore that line.
2025-09-18 10:00 AM
Primary test BL DFU with boot pin setup and are you sure USB on DK is
?
2025-09-18 2:41 PM
I was able to get into DFU with the USB by using CubeMX to configure the USB port as DFU. However, I would like to generally use the USB pins as VCP and then have the option to boot into the bootloader to get the USB to connect in DFU Mode. This way I could have both.
I am confident that the USB should work in this manner because I was able to do it if it was configured as such (if I am understanding your question correctly).
2025-09-19 9:46 AM
No you missunderstand. Normal way use internal bootloader is HW BOOT0 pin setup on HW reset. When this work for you ( show device in windows devices list and connect in CubeProgrammer.) , continue with try call from your code. And connector USB for this is CN13 only on DK.