cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H745XIHX entering bootloader in code: Switch USB from VCP to DFU on User Input

Hi all,

I am a newer STM32 programmer, and I have been working on the STM32H745 Discovery board for the last few months. Something that I would like to do is be able to switch into USB DFU Mode within a UI that I have made for this board. I took inspiration from this post and changed the address to the appropriate one for the STM32H745. I would like to prerequisite that the USB port is initially configured as a VCP/CDC device. Here is the code that I have:

void (*SysMemBootJump) (void);

void USB_BootloaderInit()
{
	volatile uint32_t addr = 0x1FFF9800;	//from AN2606

	__disable_irq();

	// Reset USB OTG_FS

	// Disable caches
	SCB_DisableICache();
	SCB_DisableDCache();

	// Remap vector table
	HAL_RCC_DeInit();		//Reset the system clock
	SysTick->CTRL = 0;		//Reset the  SysTick Timer
	SysTick->LOAD = 0;
	SysTick->VAL  = 0;
	SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));	//Point the PC to the System Memory reset vector
	__set_MSP(*(uint32_t *)addr);	//Set the Main Stack Pointer

	SysMemBootJump();				//Run our virtual function defined above that sets the PC

	while(1);
}

 Now, to test this code, I am simply calling it at the very beginning of main as such:

int main(void)
{

  /* USER CODE BEGIN 1 */
USB_BootloaderInit();


  /* USER CODE END 1 */
/* USER CODE BEGIN Boot_Mode_Sequence_0 */
  int32_t timeout;
/* USER CODE END Boot_Mode_Sequence_0 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

/* USER CODE BEGIN Boot_Mode_Sequence_1 */
  /* Wait until CPU2 boots and enters in stop mode or timeout*/
  timeout = 0xFFFF;
  while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
  if ( timeout < 0 )
  {
  Error_Handler();
  }

But, when I get on STM32Cube Programmer, I do not see the device. I have tried using the debugger, but I think I am running into different issues because of the dual core nature of this. I would get errors from random things. The one that particularly stumped me is this line:
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4))); //Point the PC to the System Memory reset vector

would consistently trigger a hard fault error (IMPRECISSER)

I have looked around the forum posts that exist and I do not think I have found something quite like my issue.

Thank you for your time!

 

1 REPLY 1
TDK
Super User

Here is code for jumping to the bootloader that works. Note the line that says __enable_irq.

How to jump to system bootloader from application ... - STMicroelectronics Community

 

Don't jump from within an interrupt.

Don't disable caches that aren't enabled.

Ensure the M4 core isn't booting, or has code that won't interfere with the bootloader.

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