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-23 3:31 AM
Hi @ilikeCODINGbutitdoesntlikeME
DFU and CDC are different USB protocols. You need to implement a composite device for your application to switch to DFU mode.
Here is an article on how to implement the USB device composite class USB DFU + HID. You can follow the same principle to implement your CDC application.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-09-23 5:12 AM
I've determined it has something to do with the stuff being initialized on startup, so I ended up just having a check flag that is written in a RAM section that does not get overwritten. Then, on reset, the assembly code forces the STM32H745 into the bootloader. This has been a very repeatable way to do this, although I am unsure if CubeIDE/CubeMX overwrite this file yet.
Thank you all for your help!