Cannot get STM32F446 into USB DFU mode to upload new firmware
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-05 8:10 AM
I am trying to get my STM32F446RE (using STM32CubeIde) into USB DFU mode via firmware rather than using the RST and BOOT0 inputs which are going to switches on the board. I know this is doable but for some reason it is not working for me
whenever I go into JumpToDFUBootloader(void); the windows host computer does nothing looking at windows device manager I should see "STM32 BOOTLOADER" under USB Devices but I do not see this which means the correct process
to go into DFU mode is not happening, I notice that if I jump the BOOT0 pin high and execute JumpToDFUBootloader() it does go into USB DFU mode and I can see the "STM32 BOOTLOADER" but unfortunately I DO NOT want to rely
on my BOOT0 or RST input pins I just want to go into DFU mode upload new firmware and repower the system to re-initialize into normal operating mode afte a firmware update.
Any suggestions or help with this would be greatly apprciated
My code is below:
/*
///////These below are before and when entering my main() function /////////
#define BOOTLOADER_ADDR 0x1FFF0000U
extern USBD_HandleTypeDef hUsbDeviceFS;
BooterFlag = Read_ext_uint8_eeprom(BOOTFLAG_LOC); /// I am reading a location on I2C EEPROM to see if my bootload flag is active
HAL_Delay(50);
printf("\nBooterFlag = %u\n",BooterFlag); // for debug
if((BooterFlag != 0) && (BooterFlag != 1))
{ BooterFlag = 0;
Write_ext_8bit_eeprom(BOOTFLAG_LOC,BooterFlag);
}
else if(BooterFlag == 1)
{
printf("Jumping to Boot-loader\n\r");
Write_ext_8bit_eeprom(BOOTFLAG_LOC,0);
HAL_Delay(100);
JumpToDFUBootloader();
}
*/
////////////// Here is my function to get me to DFU Boot-Loader //////////
void JumpToDFUBootloader(void) {
void (*SysMemBootJump)(void);
// Disable interrupts
__disable_irq();
// Stop USB device
USBD_Stop(&hUsbDeviceFS);
USBD_DeInit(&hUsbDeviceFS);
// Disable USB interrupt
HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
// Reset USB OTG FS
__HAL_RCC_USB_OTG_FS_FORCE_RESET();
HAL_Delay(10);
__HAL_RCC_USB_OTG_FS_RELEASE_RESET();
// Enable USB OTG FS clock for system bootloader
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
// De-init HAL and peripherals
HAL_RCC_DeInit();
HAL_DeInit();
// Disable SysTick
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
// Remap system memory
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
// Set MSP and jump to system memory
__set_MSP(*((volatile uint32_t *) BOOTLOADER_ADDR));
SysMemBootJump = (void (*)(void)) (*((volatile uint32_t *)(BOOTLOADER_ADDR + 4)));
// Jump
SysMemBootJump();
// Should never reach here
while (1);
}
- Labels:
-
STM32F4 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-05 10:42 AM - edited ‎2025-06-05 10:43 AM
The chip needs to be in an as-reset state. All individual interrupts disabled, clocks at default, etc, but interrupts globally enabled. You are not enabling interrupts globally. Could be other problems.
Example code here:
How to jump to system bootloader from application ... - STMicroelectronics Community
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-05 11:07 AM
I have looked the post you directed me to by B. Montanari and actually implemented his identical code and still have the same issue, it is not going into USB DFU mode. Obviously, there is something I am missing here that I cannot seem to find.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-05 11:17 AM
Are you sure you design meet AN2606 USB on PA11/12 and HSE as noted ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-05 11:34 AM
Yes, both PA11 and PA12 are using push-pull mode, the fact is the USB DFU loader works just fine if I go into my JumpToDFUBootloader() function and hold the BOOT0 input high which is what I am trying to avoid using or if I do a reset and hold the BOOT0 input high
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-05 11:40 AM - edited ‎2025-06-05 11:40 AM
Okay, so that code is not the issue here, if you're using the known good code in the linked post. The code in the OP will not work. What other peripherals and clock settings do you change? They need to be in as-reset state.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-05 12:48 PM
I have de-initialized every peripheral that I am using and I am still having the same issue. I am getting to the point where I may just use a not so elegant solution and that is just to use an external D-Flop on the BOOT0 pin that I can set via an IO pin just prior to doing a NVIC_SystemReset() to get me into the USB DFU mode, then just recycle the power after updating the firmware. I guess the other option is to write a full blown boot-loader that works over the USB virtual comm port which is not that simple.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-06 1:29 AM
Primary dont jump from running system, place jump on main first lines before any init. Do it working ...
I use for example IWDG reset and get flag for this.
