cancel
Showing results for 
Search instead for 
Did you mean: 

JumpToBootloader() not working on STM32G071 thru UART

AndersonKKK
Associate

Post edited by ST moderator to be inline with the community rules for the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code.

Hi,
I want to jump to system memory boot with SW using UART1.
I tested it using code I found by searching forums and the internet, but it doesn't work.
For reference, the STM32G071 shares the BOOT0 and SWCLK pins. By pulling the BOOT0 pin high and resetting the device, I can perform a system memory boot. After that, I connected the UART connect in STM32CubeProgrammer and verified the update.

However, after jumping to the code below and pressing the UART connect in STM32CubeProgrammer, the following message appears and the device fails.

RTS low
DTR low
Serial Port COM15 is successfully opened.
Port configuration: parity = even, baudrate = 115200, data-bit=8, stop-bit=1.0, flow-control=0ff
Timeout error occurred while waiting for acknowledgment.
Error: Activating device: KO. Please verify the boot mode configuration...

For reference, the OB settings are
nBOOT_SEL=0, nBOOT1=1, nBOOT0=1.
I'd appreciate it if you could tell me where the problem is.

 

void JumpToBootloader(void)

{

enum {C0, F030x8, F030xC, F03xx, F05, F07, F09, F10xx, F105, F107, F10XL, F2, F3, F4, F7, G0, G4, H503, H563, H573, H7x, H7A, H7B, L0, L1, L4, L5, WBA, WBX, WL, U5};



#define MCU G0 //Define here the MCU being used

/* USER CODE END PD */



uint32_t i=0;

void (*SysMemBootJump)(void);





/* Set a vector addressed with STM32 Microcontrollers names */

/* Each vector position contains an address to the boot loader entry point */



volatile uint32_t BootAddr[33];



BootAddr[C0] = 0x1FFF0000;

BootAddr[F030x8] = 0x1FFFEC00;

BootAddr[F030xC] = 0x1FFFD800;

BootAddr[F03xx] = 0x1FFFEC00;

BootAddr[F05] = 0x1FFFEC00;

BootAddr[F07] = 0x1FFFC800;

BootAddr[F09] = 0x1FFFD800;

BootAddr[F10xx] = 0x1FFFF000;

BootAddr[F105] = 0x1FFFB000;

BootAddr[F107] = 0x1FFFB000;

BootAddr[F10XL] = 0x1FFFE000;

BootAddr[F2] = 0x1FFF0000;

BootAddr[F3] = 0x1FFFD800;

BootAddr[F4] = 0x1FFF0000;

BootAddr[F7] = 0x1FF00000;

BootAddr[G0] = 0x1FFF0000;

BootAddr[G4] = 0x1FFF0000;

BootAddr[H503] = 0x0BF87000;

BootAddr[H563] = 0x0BF97000;

BootAddr[H573] = 0x0BF97000;

BootAddr[H7x] = 0x1FF09800;

BootAddr[H7A] = 0x1FF0A800;

BootAddr[H7B] = 0x1FF0A000;

BootAddr[L0] = 0x1FF00000;

BootAddr[L1] = 0x1FF00000;

BootAddr[L4] = 0x1FFF0000;

BootAddr[L5] = 0x0BF90000;

BootAddr[WBA] = 0x0BF88000;

BootAddr[WBX] = 0x1FFF0000;

BootAddr[WL] = 0x1FFF0000;

BootAddr[U5] = 0x0BF90000;



/* Disable all interrupts */

__disable_irq();



/* Disable Systick timer */

SysTick->CTRL = 0;



/* Set the clock to the default state */

HAL_RCC_DeInit();



/* Clear Interrupt Enable Register & Interrupt Pending Register */

for (i=0;i<5;i++)

{

NVIC->ICER[i]=0xFFFFFFFF;

NVIC->ICPR[i]=0xFFFFFFFF;

}



/* Re-enable all interrupts */

__enable_irq();



/* Set up the jump to boot loader address + 4 */

SysMemBootJump = (void (*)(void)) (*((uint32_t *) ((BootAddr[MCU] + 4))));



/* Set the main stack pointer to the boot loader stack */

__set_MSP(*(uint32_t *)BootAddr[MCU]);



/* Call the function to jump to boot loader location */

SysMemBootJump();



/* Jump is done successfully */

while (1)

{

/* Code should never reach this loop */

}

}
2 REPLIES 2
gbm
Principal

Read some of the threads on the bootloader stuff - you will find many suggestions there. For a Quick start, set the optimization level to -O2 or -O1 - the code generated with -O0 for bootloader jump is usually broken.

You may also check this header file for some ideas:

https://github.com/gbm-ii/STM32_Inc/blob/main/cm_boot.h

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
SirineST
ST Employee

Hello @AndersonKKK 

I have two recommendations for you.

1. De-initialize UART1 peripheral: please add HAL_UART_DeInit(&huart1) after HAL_RCC_DeInit() in your code. This ensures that UART1 is properly de-initialized and in reset state before jumping.

2. Verify Option Bytes settings: In addition to the OB settings nBOOT_SEL=0, nBOOT1=1, nBOOT0=1, could you please make sure that nSWBoot0 = 1.

For further details, you can consult AN2606

With regards

If your question is answered, please close this topic by clicking "Accept as Solution"