cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 and FLASH registers

JR2963
Senior II

I have a question regarding STM32L0. I am interested in which address the registers like FLASH_ACR, FLASH_PECR, etc., are located. In the datasheet, I only see their offsets, but not the absolute value is it maybe 0x1FF8 0000?.
Also I would also like to know if it is possible to read from the mentioned registers like FLASH_SR, etc., when the MCU is locked at Level 1? Because to unlock it (using an external debugger).

 

Why all this? I want to erase mcu no matter if it is or is not in Level1 or Level 0.

Thank you Jan.

3 REPLIES 3
Danish1
Lead II

Have you checked the Reference Manual for your stm32L0?

For stm32l0x1 for example, it is stated in section 2.2 "System and memory overview:Memory organisation"

 

Table 3. STM32L0x1 peripheral register boundary addresses(1) (continued)

RM0377

Bus

Boundary address

Size (bytes)

Peripheral

Peripheral register map

NVM

0X0800 0000 - 0X0802 FFFF

up to 192 K

Flash program memory

-

0x0808 0000 - 0x0808 17FF

up to 6 K

Data EEPROM

-

0x1FF0 0000 - 0x1FF0 1FFF

8K

System memory

-

0x1FF8 0020 - 0x1FF8 007F

96

Factory option bytes

-

0x1FF8 0000 - 0x1FF8 001F

32

User option bytes

-

1. Refer to Table 1: STM32L0x1 memory density, to Table 2: Overview of features per category and to the device datasheets for the GPIO ports and peripherals available on your device. The memory area corresponding to unavailable GPIO ports or peripherals are reserved.

Edit: Added removal of code protection.

If your debugger doesn't provide direct control of code-protection level, you might have to do what I do. I download a program like this into RAM: (I use Crossworks; you'll have to have your own way to monitor what's going on to replace the "debug_printf" statements)

/* main.c for RemoveCodeProtection */

#include <cross_studio_io.h>
#include "stm32wlxx_hal.h"

void main(void) {
    FLASH_OBProgramInitTypeDef clearRdp;
    HAL_Init();
    HAL_InitTick(TICK_INT_PRIORITY);
    /*	Unlock the Flash to	enable the flash control register access *************/
    HAL_FLASHEx_OBGetConfig(&clearRdp);
    if (clearRdp.RDPLevel == OB_RDP_LEVEL_0) {
        debug_printf("Code protection already disabled\n");
    } else {
        debug_printf("Trying to disable code protection. Power-cycle after 10 seconds\n");
        HAL_FLASH_Unlock();
      /* Clear OPTVERR bit set on virgin samples */
      __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); 
        /* Unlock	the	Options	Bytes *************************************************/
        HAL_FLASH_OB_Unlock();
        clearRdp.RDPLevel = OB_RDP_LEVEL_0;
        clearRdp.OptionType = OPTIONBYTE_RDP;
        HAL_StatusTypeDef rc = HAL_FLASHEx_OBProgram(&clearRdp);
        if (rc == HAL_OK) {
            HAL_FLASH_OB_Launch();
            HAL_FLASH_OB_Lock();
            debug_printf("Successful\n");
        } else
            debug_printf("Failed\n");
    }
}

waclawekjan_0-1705660747205.png

JW

 

This is exactly what I was looking for, Unfortunately I still can not make mass erase of my MCU. I found this: It should erase MCU when is in Level1

JR2963_0-1705662445784.png

So I made it

RDP_UNLOCK = 0xAA

PRGKEY1 = 0x8C9DAEBF
PRGKEY2 = 0x13141516 
PEKEY1 = 0x89ABCDEF
PEKEY2 = 0x02030405
OPTKEY1 = 0xFBEAD9C8
OPTKEY2 = 0x24252627

SECTION_USER_OB = 0x1FF80000
FLAHS_OB_BASE = 0x40022000

FLASH_PECR = FLAHS_OB_BASE+0x4
FLASH_PEKEYR= FLAHS_OB_BASE+0x0C
FLASH_OPTKEYR = FLAHS_OB_BASE+0x14
FLASH_OPTR = FLAHS_OB_BASE+0x1C
FLASH_PRGKEYR = FLAHS_OB_BASE+0x10
FLASH_SR = FLAHS_OB_BASE+0x18

def massErase(self):
    self.unlockOptionBytesArea()
    self.programoptionBytes(0x00AA)
...
def unlockOptionBytesArea(self):
        self.busy_wait()
        tmp = self.readU32Mem(FLASH_PECR)
        if (tmp & PECR_PELOCK_BIT) == 0: # 
            if tmp & PECR_OPTLOCK_BIT == 1 : 
                if self.writeU32ToMem(FLASH_OPTKEYR,OPTKEY1) == True:
                    if self.writeU32ToMem(FLASH_OPTKEYR,OPTKEY2) == True:
                        self.busy_wait()
                        return True

 def programoptionBytes(self,val):
        val = self.option_bytes_word(val)
        self.writeU32ToMem(SECTION_USER_OB,val)
        self.busy_wait()
        flash_sr = self.readU32Mem(FLASH_SR)
        if flash_sr & SR_EOP != 0:
            self.writeU32ToMem(FLASH_SR, SR_EOP)