cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G474 jump to ST Bootloader without Boot0 pin

Avellar
Associate

Hi,

I'm trying to boot to the system memory so I could use ST bootloader (USB-DFU in mind), but unfortunately not succeeded.

I have a custom board with a STM32G474RE and another similar version with a STM32G473RB. I cannot use the PB8/Boot0 pin, cause I am using the pin for the CAN_RX with a MCP2562 chip. I have the Option Bytes as follow:

BFB2 = 0, nBOOT1 = 1, nSWBOOT0 = 0, nBOOT0 = 0, BOOT_LOCK = 0

This is what is written in the STM32G4 Manual to disable PB8 and make a sw jump to the bootloader but doesn't work.

I also have tried to boot (at the addr.: 0x1FFF0000) directly from the main(), with the function below:

__attribute__((naked, noreturn)) void BootJumpASM(uint32_t SP, uint32_t RH)
{
	__asm("MSR    MSP,r0");
	__asm("BX     r1");
}
void bl_flash_jump_to_address(uint32_t address)
{
	/* BootJump done as explained by ARM documentation */
	/* Disable SysTick and clear its exception pending bit */
	SysTick->CTRL = 0;
	SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
 
	/* Disable individual fault handlers */
	// not necessary here (?)
 
	/* Activate the MSP, if the core is
	 * found to currently run with the PSP */
	if (CONTROL_SPSEL_Msk & __get_CONTROL())
	{/* MSP is not active */
		__set_MSP(__get_PSP());
		__set_CONTROL(__get_CONTROL() & ~CONTROL_SPSEL_Msk);
	}
 
	/* Load the vector table address of the user application */
	SCB->VTOR = address;
 
	/* Set the MSP to the value in user application VTOR
	 * and then load the PC with the reset vector value
	 * of the user application */
	BootJumpASM(*(volatile uint32_t*) address,
			*(volatile uint32_t*) (address + 4U));
}
 
int main(void)
{
    __disable_irq();
    SYSCFG->MEMRMP = 0x01; // 0x0000 0000 map to system memory
    bl_flash_jump_to_address(0x1FFF0000) // address of the system memory
}

Some observations:

1- The USB on my custom board and the board itself works fine. I can run my applications on it and all peripherals (UART, SPI, GPIO, HSE, ADC, DAC etc). I can set USB-CDC or I can also set USB-DFU generated by CubeMX with no problem.

2- The code to make the jump works, because I can make the jump to my app (ie. address 0x8008000)

3 - The board is powered by USB 5V and converted to 3V3, that goes to all the VDD & VBAT pins

4 - I have a Nucleo Board STM32G474, I tested with the Option Bytes, and with the code above. I can jump to the ST Bootloader with no issue - which makes me more confuse.

Am I am missing something or can it be a Hardware issue on my custom board?

Thanks

4 REPLIES 4
KnarfB
Principal III

You might check here https://stm32f4-discovery.net/2017/04/tutorial-jump-system-memory-software-stm32/, especially the USB/irq discussion in the comments. Disclaimer: not using it myself.

hth

KnarfB

Uwe Bonnes
Principal III

This should go to the start of the startup code. To much can have happened at main().

TDK
Guru

Don’t disable interrupts globally. The USB boot loader needs them enabled in order to function.

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

Thanks for the answers,

I indeed commented the disable_irq call for the USB-DFU to work, but still works only in the Nucleo STM32G474 and not on my custom board. It also should work with the Option Bytes regardless of what the user code is.

I suspect it might be HW. I have other custom boards with the STM32G431KB and STM32G491KE, also similar circuit for USB and power, but they have the PB8 pin free and I use a switch to set the ST Bootloader. Works fine.

I could not find in the manual any connection that would prevent from booting to the ST bootloader.