cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WLE5CC MCU brick when trying to set Brownout Reset level

IFant.1
Associate II

Greetings

I have been trying to set the BOR option byte via software in a STM32WLE5CC (as part of a RAK3172 evaluation board), but even following various guides i have not been successful in this endeavor, often resulting in the MCU being bricked and requiring intervention via CubeProgrammer to reset the corrupted option bytes followed by reflashing of the firware via CubeIDE.

The code is as follows:

int main(void)
{
	/* USER CODE BEGIN 1 */
 
	/* USER CODE END 1 */
 
	/* MCU Configuration--------------------------------------------------------*/
 
	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();
 
	/* USER CODE BEGIN Init */
 
	/* USER CODE END Init */
 
	/* Configure the system clock */
	SystemClock_Config();
 
	/* USER CODE BEGIN SysInit */
	MX_GPIO_Init();
 
	/* USER CODE END SysInit */
 
	/* Initialize all configured peripherals */
        SystemApp_Init();
	/* USER CODE BEGIN 2 */
 
 
 
	HAL_StatusTypeDef status;
	FLASH_OBProgramInitTypeDef FLASH_Handle;
 
	if ( (FLASH->OPTR & FLASH_OPTR_BOR_LEV_Msk) != OB_BOR_LEVEL_4){
 
		HAL_FLASHEx_OBGetConfig(&FLASH_Handle);
 
		FLASH_Handle.OptionType = OPTIONBYTE_USER;
		FLASH_Handle.UserConfig = FLASH_Handle.UserConfig | (uint32_t)OB_BOR_LEVEL_4;
		FLASH_Handle.UserType = OB_USER_BOR_LEV;
		status= HAL_FLASH_Unlock();
		status= HAL_FLASH_OB_Unlock();
 
		status=HAL_FLASHEx_OBProgram(&FLASH_Handle);
		if (status != HAL_OK)
		{
 
			APP_LOG(TS_OFF, VLEVEL_M, "Error during programming %x\r\n", (uint32_t)status);
			return;
		}
 
 
		HAL_FLASH_OB_Lock();
					HAL_FLASH_Lock();
 
 
		status=HAL_FLASH_OB_Launch();
		if(status==HAL_ERROR){
			APP_LOG(TS_OFF, VLEVEL_M, "Error during launch\r\n");
		}
 
 
	}
 
 
 
 
	APP_LOG(TS_OFF, VLEVEL_M, "FLASH->OPTR is = %X\r\n", (uint32_t)READ_REG(FLASH->OPTR));
 
	/* USER CODE END 2 */
 
	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1)
	{
 
		//APP_LOG(TS_OFF, VLEVEL_M, "Loop\r\n");
 
		/* USER CODE BEGIN 3 */
	}
	/* USER CODE END 3 */
}

In this configuration, HAL_FLASH_OB_Launch returns HAL_ERROR rather than causing a reset of the MCU to load the new option bytes, thus resulting in the option bytes not being effectively written to the register, successive power cycling (with or without a debugger attached) show that the option bits were not overwrote

When removing both unlock functions, the MCU hangs/bricks with power cycling failing to resolve the issue, the RDP field is corrupted to FF and some other parts of the flash seems corrupted as well thus preventing reflashing via CubeIDE

Only intervention through CubeProgrammer to reset the option bytes followed by reflashing via CubeIDE has shown any effectiveness at recovering from said state.

Any suggestion in how to fix this issue? Thanks in advance.

Edit: just in case they might be needed, i attach images of the Option Bytes read from the ST-LINK

Edit #2: i have noticed that during the various write operations (es: in FLASH_OB_OptrConfig), the register value does not appear to be updated, whether this is a limitation of the debugger or of the printout via APP_LOG erroneously returning a old value i do not know

14 REPLIES 14

Unfortunately, even pressing the hardware reset button (that should cause an hardware reset) does not seem to help, the option bytes are not loaded (with the exception of the corrupted RDP level) and the device does not seem to give signs of life (until i start changing the option bytes with CubeProgrammer AND re-flash the program with CubeIDE)

Furthermore, i've noticed another thing, when calling HAL_FLASHEx_OBProgram the FLASH->OPTR register should be written to, thus changing in value.

However this does not seem to happen (checked both with CubeIDE debugging and with UART print), it always remains 0x3FFF00AA

Ok, i will try on my side and get back to you.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Another thing i noticed, in case it could help

The reference manual for the MCU (RM0461) says that the OPTR register's reset value should be 0x3FFFF0AA

This corresponds to setting all non reserved option bytes to 1 except BOOT_LOCK and BOR_LEV, both set at 0, and RDP, set to AA

however, when using CubeProgrammer to change all the option bits to what should be their default value, i see that my OPTR register is 3FFF70AA, meaning that the bit 15 is 0 instead of 1

Could this have any bearing on why the device is behaving in such a way? Thanks in advance

EDIT: using Cubeprogrammer to first set OPTR (at 0x58004020) to the correct default value then re-flashing the program and attempting to use the Launch function i discovered something... Odd.

PREFACE: i had modified the program to set the BOR to level 1 in case it was an issue regarding the supplied voltage level being too low, that's why in this case is 200 rather than 800

At first (before Launch();) the OPTR at 0x58004020 was 3FFFF0AA (like i set it)

After the launch. the OPTR at 0x58004020 is now 3FFF01FF

But the one at 0x1FFF7800 is (well, was) 3FFFF2AA (aka the correct value i wanted to write)

However the MCU still didn't work properly (no UART messages no nothing) and, more interesting, after checking back at 0x58004020 and thenn re-checking at 0x1FFF7800, the latter shown only 0s

Checking at 0x08000000 similarly shown only 0s

My only guess is that the MCU is, on top of corrupting the OPTR at 0x58004020, also deleting the flash memory in its entirety, for some unknown reason

EDIT 2: after re-setting the 0x58004020 OPTR to RDP=AA and BOR level =1, the MCU resumed functioning (at least for now) and the code in the flash memory reappeared (albeit with the OPTR at 0x1FFF7800 being 3FFF03AA and the one at 0x58004020 being 3FFF02AA)...

I am officially flummoxed

Bruno_ST
ST Employee

Hello @IFant.1​ 

I have tested and it is working fine on my side.

Most important is that you have to avoid your program (change BOR Level) to run while STM32CubeProgrammer is changing the BOR level on his side (because STM32CubeProgrammer is changing BOR by calling HAL_FLASH_OB_Launch() (programmed executed from RAM) causing a MCU HW reboot with a loose of SWD connection to the tool. So it means that the MCU has time program to boot & execute a program (for around ~1second)

So attached program allow to change from BOR level 0 to 4 and wait 10 second before launching the sequence.

BR,

Bruno

PS: you only need to add Drivers directory with CMSIS+HAL

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Thank you Bruno but we eventually decided to set the BOR level via cubeprogrammer to sidestep the issue entirely.