cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L031 Can't unlock flash

MSvra.1
Associate

Hey,

I’m using a nucleo board: SMT32L031K6.

I’m trying to make a simple bootloader but I’m struggling at unlocking the flash. In the reference manual it states that I must perform an unlocking sequence, but I haven’t been able to do it successfully. When I try to write the first key, the key register doesn’t change and I get a WRPERR bit set in Status register but no hard fault.

I want to unlock the flash to update an app that will sit at address 0x0800 5000. Since I’m quite new to this, I’m not sure which of these I should unlock: just PE_LOCK or PE_LOCK and PRG_LOCK?

And what is causing the unlock to fail?

Here’s part of my code:

#define FLASH_SR_BSY				0
 
#define FLASH_PECR_PE_LOCK			0
#define FLASH_PECR_PRG_LOCK			1
 
// Sequence to unlock data EEPROM and FLASH_PECR register, write to FLASH_PEKEYR
#define PEKEY1 		0x89ABCDEF
#define PEKEY2		0x02030405
// Sequence to unlock Flash program memory, write to FLASH_PRGKEYR
#define PRGKEY1 	0x8C9DAEBF
#define PRGKEY2		0x13141516
 
void FLASH_Unlock(void)
{
	// Wait for Flash memory to not be busy
	while( FLASH->SR & (1 << FLASH_SR_BSY) );
 
	// Check if it is locked
	if( FLASH->PECR & (1 << FLASH_PECR_PE_LOCK) )
	{
		// Write first key
		FLASH->PEKEYR = PEKEY1;
		// Write second key
		FLASH->PEKEYR = PEKEY2;
	}
	// Check if it is locked
	if( FLASH->PECR & (1 << FLASH_PECR_PRG_LOCK) )	
	{
		// Write first key
		FLASH->PRGKEYR = PRGKEY1;
		// Write second key
		FLASH->PRGKEYR = PRGKEY2;
	}
}

2 REPLIES 2
Danish1
Lead II

Single-stepping through your code with the debugger looking at FLASH registers will fail, for the simple reason that the two writes will be interrupted by reads from your debugger.

Have you tried running the HAL example code? If that works then you need to look carefully for differences between your own code and theirs.

Do you explicitly #define things like FLASH_SR_BSY or was that just to make your example complete? I think it is much safer to #include ST-written headers.

Hope this helps,

Danish

Hey, thanks for the reply!

I ran the HAL code and that worked. I could even single step through it though I understand now why that's not ideal.

The one difference I saw was that the ACR had PRE_READ bit set ( it sets it in Hal_Init() ) but when I tried to do the same I got the Write protection error again.

It seems like it doesn't allow me to write anything to flash registers.

And yes, I write it explicitly since I'm trying to better understand low level programming and writing my own drivers. But I'll use the ST written headers now as I try to find the fault.