cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-H533RE USB custom DFU method

Sumanth_M_N
Visitor

Hello all!

Actually i am trying to use USB DFU mode of STM32H533RE Nucleo board.
I can able to enter DFU mode by using BOOT0 pin but the intention is to do software method of entering into USB DFU. After doing a lot of research on web and using some AI tools below is the code i got.

For the better understanding:
I am using USB CDC and whenever it recevies DFU over USB i am calling this function to enter to DFU mode.

void JumpToUSB_DFU(void)

{

/* Called from main() BEFORE HAL_Init() — after a software reset where

* Enter_DFU_Bootloader() already cleanly stopped USB and waited 300 ms.

* After SYSRESET: all peripherals are reset, hpcd_USB_DRD_FS.Instance = NULL. */



/* 1. Disable all interrupts globally */

__disable_irq();



/* 2. Disable ICACHE directly via register — MUST be done BEFORE disabling SysTick.

* ICACHE state persists through software reset. If we call HAL_ICACHE_Disable()

* after SysTick is off, it hangs in a HAL_GetTick() timeout loop forever. */

ICACHE->CR &= ~ICACHE_CR_EN;

/* Wait for ICACHE to go idle using a simple poll (no SysTick needed) */

uint32_t icache_timeout = 0x00FFFFFFUL;

while ((ICACHE->SR & ICACHE_SR_BUSYF) && (icache_timeout-- > 0)) { __NOP(); }



/* 3. Disable SysTick timer */

SysTick->CTRL = 0;

SysTick->LOAD = 0;

SysTick->VAL = 0;



/* 4. Clear all pending NVIC interrupt requests */

for (uint8_t i = 0; i < 8; i++) {

NVIC->ICER[i] = 0xFFFFFFFF;

NVIC->ICPR[i] = 0xFFFFFFFF;

}



/* -----------------------------------------------------------------------

* 5. CRITICAL: Enable VDDUSB power domain for the bootloader.

* After SYSRESET, PWR_USBSCR.USB33DEN resets to 0 (disabled).

* The STM32H533 ROM bootloader does NOT enable this itself.

* Without VDDUSB, the USB transceiver has no power and USB DFU

* silently fails to enumerate — this is the most common failure mode.

* HAL_PWREx_EnableVddUSB() just sets one register bit; safe here.

* ----------------------------------------------------------------------- */

HAL_PWREx_EnableVddUSB();

/* Short NOP delay for the USB 3.3V supply to stabilize (~100 us @ 64 MHz) */

for (volatile uint32_t i = 0; i < 6400UL; i++) { __NOP(); }



/* -----------------------------------------------------------------------

* 6. CRITICAL: Ensure HSI48 is ON and stable.

* The bootloader needs HSI48 for its CRS-synchronized USB clock.

* After SYSRESET it may be OFF; turn it on and wait for lock.

* ----------------------------------------------------------------------- */

SET_BIT(RCC->CR, RCC_CR_HSI48ON);

uint32_t hsi48_timeout = 200000UL;

while (!(RCC->CR & RCC_CR_HSI48RDY) && (hsi48_timeout-- > 0U)) { __NOP(); }



/* 7. Find the bootloader base address automatically.

* The exact System Memory base for STM32H533 is not reliably defined in

* all HAL versions (varies between 0x0BF80000, 0x0BF90000, 0x0BF97000).

* We scan the 0x0BF80000 - 0x0BFA0000 range for a valid vector table. */

uint32_t bootloader_base = 0;

uint32_t bootloader_sp = 0;

uint32_t bootloader_pc = 0;



for (uint32_t addr = 0x0BF80000UL; addr < 0x0BFA0000UL; addr += 0x1000UL)

{

uint32_t sp = *((volatile uint32_t*)addr);

uint32_t pc = *((volatile uint32_t*)(addr + 4));



/* Valid Vector Table signature:

* 1. SP points inside SRAM (STM32H533 RAM is 0x20000000 to 0x20044000)

* 2. PC points somewhere inside the ROM bootloader memory itself */

if ((sp >= 0x20000000UL) && (sp <= 0x20050000UL) &&

(pc > addr) && (pc < (addr + 0x10000UL)))

{

bootloader_base = addr;

bootloader_sp = sp;

bootloader_pc = pc;

break;

}

}



if (bootloader_base == 0)

{

/* Bootloader not found. Reboot to app to avoid hard fault. */

HAL_NVIC_SystemReset();

while (1);

}



/* 8. Small NOP delay (~100 ms at ~64 MHz HSI) — ensures host USB stack

* has fully processed the prior disconnect before DFU re-enumerates. */

for (volatile uint32_t i = 0; i < 6400000UL; i++) { __NOP(); }



/* 9. CRITICAL: Clear Reset Flags!

* If the ROM bootloader sees the Software Reset flag (SFTRSTF) in RCC->RSR,

* it assumes a fault occurred and immediately jumps back to Flash.

* We must clear it so the bootloader acts like it was a fresh power-on. */

RCC->RSR |= RCC_RSR_RMVF;



/* 10. Set the Vector Table Offset Register to System Memory */

SCB->VTOR = bootloader_base;

__DSB(); /* Data Sync Barrier — ensure VTOR write completes before jump */

__ISB(); /* Instruction Sync Barrier — flush pipeline */



/* 11. Set Main Stack Pointer and branch to bootloader Reset Handler */

__asm volatile (

"msr msp, %0\n\t"

"bx %1\n\t"

:

: "r" (bootloader_sp),

"r" (bootloader_pc)

: "memory"

);



/* The CPU should never reach this point */

while (1);

}


But it is not going into DFU mode at all.
It is just resetting the board. What am I missing here? If someone has faced the same issue, it would be great to help me resolve this

0 REPLIES 0