STM32F411 DFU mode strange behavior
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?
