2022-10-17 10:47 PM
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;
}
}
2022-10-17 11:17 PM
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
2022-10-18 03:16 AM
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.