Skip to main content
Visitor II
June 6, 2021
Question

STM32F411 DFU mode strange behavior

  • June 6, 2021
  • 3 replies
  • 2507 views

Hello gents!

I'm trying to implement jump to DFU mode from the app (bootloader), without usage of BOOT0 pin. Logic should be following: if the user button is pressed during device startup (USB cable plug in) more than 3 sec, then device should go to DFU mode (or read image from SD card in future plans), otherwise - jump to user app.

It works fine if delay is below 300ms, but if I increase it above 300ms - USB device is not enumerating somehow, I don't see it in dfu-util of lsusb commands. Is there any time limits for connected USB device to enumerates?

I tried to play with DP pin pull up/down, but it did not help. Also performed peripheral deinit (not sure if it is needed as I perform system reset anyway...) - did not help too.

Jump code in boot loader is following:

  • main.c
int main(void) {
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	HAL_GPIO_WritePin(USB_DP_Port, USB_DP_Pin, GPIO_PIN_RESET);
	MX_SPI1_Init();
	led_init();
 led_setIntensity(3);
	MX_USB_DEVICE_Init(); // USB init for future CDC usage
	uint32_t timeoutMs = HAL_GetTick() + 3000; // button press delay. Works fine if delay is < 300 ms
	if (HAL_GPIO_ReadPin(BUT_PIN_GPIO_Port, BUT_PIN_Pin) == GPIO_PIN_RESET) {
		stringToLED(" -BOOT- ", 0); 
		while (HAL_GetTick() < timeoutMs) {
			if (HAL_GPIO_ReadPin(BUT_PIN_GPIO_Port, BUT_PIN_Pin) == GPIO_PIN_SET) {
				Run_App(); // jump to user app if button is released within button press delay
			}
		}
		HAL_GPIO_WritePin(USB_DP_Port, USB_DP_Pin, GPIO_PIN_SET);
		stringToLED("DFU ON", 0);
		*((unsigned long *)0x2001FFF0) = RESET_TO_BOOTLOADER_MAGIC_CODE; // DFU mode flag to read in System_Init
		MX_USB_DEVICE_DeInit();
		NVIC_SystemReset(); // Reset to jump in System_ Init
	} else {
		Run_App();
	}
	while (1) {
	}
}
  • system_stm32f4xx.c
void SystemInit(void)
{
 
 if ( *((unsigned long *)0x2001FFF0) == RESET_TO_BOOTLOADER_MAGIC_CODE ) { // read DFU mode flag
 *((unsigned long *)0x2001FFF0) = 0; // Reset it
 __set_MSP(0x20020000); // set stack pointer to SRAM end
 // 0x1fff0000 is "System Memory" start address for STM32 F4xx
 SysMemBootJump = (void (*)(void)) (*((uint32_t *) 0x1fff0004)); // Point the PC to the System Memory reset vector (+4)
 SysMemBootJump(); // jump to System memory code
 while (1);
 }
...
}

Any thoughts on it?

    This topic has been closed for replies.

    3 replies

    Super User
    June 6, 2021

    Consider delaying initialization of USB until after you enter RunApp.

    Or add a 1s or so delay just before NVIC_SystemReset so the system has time to realize the USB device was disconnected and tries to reenumerate it again.

    Visitor II
    June 7, 2021

    As you can see in code I have 3 sec delay in while loop before enter SystemReset, and DFU doesn't work with this delay. But if I reduce it to 300 ms or less, then it is initializing normally as DFU device.

    Run_App is not affected here at all, it performs jump to user app if the button is not pressed at startup.

    Super User
    June 7, 2021

    Your delay is before MX_USB_DEVICE_DeInit, not after.

    Disconnecting a USB device and immediately connecting another device can trip up windows because it expects the original device to still be there.

    Visitor II
    June 8, 2021

    I found bootloader timing description in AN2606 but it is about minimum timing for bootloader initialization. In my case I have delay before device reset and bootloader init.0693W00000BaMqZQAV.png

    Super User
    June 8, 2021

    According to this, the device (DFU or normal firmware) must enumerate within ~ 1.5 s. after the host detects attachment on the USB port.

    "the hub driver will attempt to retry enumeration up to 3 times by returning to the beginning of the “First Port Reset�? state. 

    A delay of 500ms occurs between each retry to allow the device to settle. 

    If the port reset times out on the 3rd retry, enumeration will be cancelled and an “Unknown Device�? will be reported".

    So, do not let the host detect attachment until you're ready to enumerate.

    -- pa