cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F411 DFU mode strange behavior

d.borodaenko
Associate II

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?

7 REPLIES 7
TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".

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.

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.

If you feel a post has answered your question, please click "Accept as Solution".

Ok, may be reasonable, will try to rearrange or add delay after DeInit. Thanks.

No, delay before SysetReset did not help...

Still no DFU if delay between USB plug in and reset to DFU mode is more than 300 ms.

d.borodaenko
Associate II

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

Pavel A.
Evangelist III

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