cancel
Showing results for 
Search instead for 
Did you mean: 

Erase stm32f427 from sector 5 to sector 23

Pilous Droip
Senior

Hello,

I have STM32F427zi supply with 1V8. And I try to erase his flash from sector 5 to sector 23, but sector 23 is not erased. STM clock is set to 144MHz. Latency set after document RM0090.

https://www.st.com/resource/en/reference_manual/dm00031020-stm32f405-415-stm32f407-417-stm32f427-437-and-stm32f429-439-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf

My init clock:

void SystemClock_Config(void)
{
    uint32_t i;
 
    // max speed -> config PWR
    LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);  // 1.8V 
    while(LL_PWR_IsActiveFlag_VOS()); 
 
    // first:
    LL_FLASH_SetLatency(LL_FLASH_LATENCY_7);
 
    if (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_7)
    {
    }
 
    //LL_PWR_DisableOverDriveMode();
 
    // start HSE
    LL_RCC_HSE_Enable();
    __NOP();
 
    // Wait till HSE is ready
    while (LL_RCC_HSE_IsReady() != 1)
    {
        __NOP();
    }
 
    //
    LL_PWR_EnableBkUpAccess();
    LL_RCC_ForceBackupDomainReset();
    LL_RCC_ReleaseBackupDomainReset();
    LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_HSE);
    LL_RCC_SetRTC_HSEPrescaler(LL_RCC_RTC_HSE_DIV_25);
    LL_RCC_EnableRTC();
 
    // PLL
    LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_25, 288, LL_RCC_PLLP_DIV_2);
    LL_RCC_PLL_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_25, 288, LL_RCC_PLLQ_DIV_6);
    LL_RCC_PLL_Enable();
 
    /* Wait till PLL is ready */
    while (LL_RCC_PLL_IsReady() != 1)
    {
      __NOP();
    }
 
    LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
    LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_4);
    LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
 
    // Wait till System clock is ready
    while (LL_RCC_SYS_CLKSOURCE_STATUS_PLL != LL_RCC_GetSysClkSource())
    {
      __NOP();
    }
 
    //
    LL_Init1msTick(144000000);
    LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
    LL_SetSystemCoreClock(144000000);
    LL_RCC_SetTIMPrescaler(LL_RCC_TIM_PRESCALER_TWICE);
 
 
    // clock enable
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CCMDATARAM);
 
    // MCU FLASH
    LL_FLASH_DisablePrefetch();
    LL_FLASH_EnableInstCache();
    LL_FLASH_EnableDataCache();
 
}

Unlock and lock function

int OCFLASH_Unlock(void)
{
    if (!(FLASH->CR & FLASH_CR_LOCK))
        return OCFLASH_ERR_OK;
 
    /*
     * user manual ST RM0410 rev 4, page 109
     * section Flash key register
     */
    FLASH->KEYR = 0x45670123;
    FLASH->KEYR = 0xCDEF89AB;
 
    return (FLASH->CR & FLASH_CR_LOCK) ?
            OCFLASH_ERR_LOCKED :
            OCFLASH_ERR_OK;
}
 
void OCFLASH_Lock(void)
{
    FLASH->CR |= FLASH_CR_LOCK;
}
 
int OCFLASH_IsLocked(void)
{
    return (FLASH->CR & FLASH_CR_LOCK);
}

And here is my erase function:

int OCFLASH_SectorErase(int sector)
{
    if (OCFLASH_IsLocked())
        return OCFLASH_ERR_LOCKED;
 
    while (FLASH->SR & FLASH_SR_BSY) {
    }
 
    // set Parallelism Size
    FLASH->CR &= ~FLASH_CR_PSIZE_Msk;
    FLASH->CR |= 0 << FLASH_CR_PSIZE_Pos;
    // set Sector Number
    FLASH->CR &= ~FLASH_CR_SNB_Msk;
    FLASH->CR |= sector << FLASH_CR_SNB_Pos;
    // select Erase action and Start
    FLASH->CR |= FLASH_CR_SER | FLASH_CR_STRT;
 
    // as advised by the manual
    __DSB();
 
    while (FLASH->SR & FLASH_SR_BSY) {
    }
 
    // clear the erase action bit
    FLASH->SR &= ~FLASH_CR_SER_Msk;
 
    if (FLASH->SR & FLASH_SR_ERROR_Msk) {
        ocflash_statusreg = FLASH->SR;
        FLASH->SR |= FLASH_SR_ERROR_Msk;
        return OCFLASH_ERR_STATUSREG;
    }
 
    return OCFLASH_ERR_OK;
}
 
int OCFLASH_IsErased(const void *src, size_t size)
{
    uint8_t *ptr = (uint8_t *) src;
 
    for (size_t i=0; i < size; i++) {
        if (ptr[i] != 0xff)
            return 0;
    }
 
    return 1;
}

And proces to erase memory.

for (int i = app_sector; i < 24; i++)
{
 
    	/* sector erase must internally lock & unlock the mcu flash ! */
      OCFLASH_Unlock();
      ret = OCFLASH_SectorErase(sector);
      OCFLASH_Lock();
}
 
// efter erase check OCFLASH_IsErased

For check I use debugger to view data in flash memory. At the picture, you can see that flash memory is wrong erased. The last 0x081FFFFF is end of sector 23.

Any idea, what is wrong?

And other:

I use STM32CubeProgrammer, where I use their new fcnt: Registers (Beta). I set STM32F427and there is for LATENCY only 3 bits. But in the RM0090 document and datasheet is writen, that STM32F427 has 4 bits for latency.

8 REPLIES 8

This is probably ART's Data Cache.

JW

Flush any pending error/status when starting out.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pilous Droip
Senior

I modificated function:

  1. Erase
  2. Flush
  3. Check erase

And the problem is still there. Erase and check FLASH are at the top of the topic.

And flush:

void OCFLASH_CacheFlush(void)
{
 
	// no separate I/D cache for CM-4
 
	// CM-4 does indeed have a I/D "cache" but it is a part of FLASH IP core,
	// not a separate CPU cache (as it is for CM-7).
 
	__NOP();__NOP();__NOP();__NOP();
	__DSB();__ISB();
	__NOP();__NOP();__NOP();__NOP();
	LL_FLASH_DisablePrefetch();
	__NOP();__NOP();__NOP();__NOP();
	__DSB();__ISB();
	__NOP();__NOP();__NOP();__NOP();
	LL_FLASH_DisableInstCache();
	__NOP();__NOP();__NOP();__NOP();
	__DSB();__ISB();
	__NOP();__NOP();__NOP();__NOP();
 
	__NOP();__NOP();__NOP();__NOP();
	__DSB();__ISB();
	__NOP();__NOP();__NOP();__NOP();
	LL_FLASH_EnableInstCache();
	__NOP();__NOP();__NOP();__NOP();
	__DSB();__ISB();
	__NOP();__NOP();__NOP();__NOP();
}

JW: What do you think of the ART's Data Cache?

Pilous Droip
Senior

An error was found.

int OCFLASH_SectorErase(int sector)
{
    if (sector < 0 || sector >= OCFLASH_SECTOR_COUNT)
        return OCFLASH_ERR_ADDR;
    if (OCFLASH_IsLocked())
        return OCFLASH_ERR_LOCKED;
 
    while (FLASH->SR & FLASH_SR_BSY) {
    }
 
    /*
     Bits 7:3 SNB[3:0]: Sector number
		These bits select the sector to erase.
		0000: sector 0
		0001: sector 1
		...
		01011: sector 11
		01100: not allowed
		01101: not allowed
		01110: not allowed
		01111: not allowed
		10000: section 12  (bank 2 sector 0)
		10001: section 13
		...
		11011 sector 23
		11100: not allowed
		11101: not allowed
		11110: not allowed
		11111: not allowed
     */
 
    /* F42x, F7xx: Need to add offset of 4 when sector higher than FLASH_SECTOR_11 */
    if (sector > 11)
    {
    	sector += 4;
    }
 
    // set Parallelism Size
    FLASH->CR &= ~FLASH_CR_PSIZE_Msk;
    FLASH->CR |= OCFLASH_PSIZE << FLASH_CR_PSIZE_Pos;
    // select Erase action and set Sector Number
    FLASH->CR &= ~FLASH_CR_SNB_Msk;
    FLASH->CR |= FLASH_CR_SER | (sector << FLASH_CR_SNB_Pos);
    // Start
    FLASH->CR |= FLASH_CR_STRT;
 
    // as advised by the manual
    __DSB();
 
    while (FLASH->SR & FLASH_SR_BSY) {
    }
 
    // clear the erase action bit
    FLASH->CR &= ~FLASH_CR_SER_Msk;
    FLASH->CR &= ~FLASH_CR_SNB_Msk;
 
    //
    if (FLASH->SR & FLASH_SR_ERROR_Msk) {
        ocflash_statusreg = FLASH->SR;
        FLASH->SR |= FLASH_SR_ERROR_Msk;
        return OCFLASH_ERR_STATUSREG;
    }
 
    return OCFLASH_ERR_OK;
}

If the sector is bigger >11 you must increment setor +4.

The debugger might've presented data from the ART Data Cache. Similarly as you disable/enable the instruction cache above, you should do with data cache, too.

True, the data cache is 4 lines x 128 bits i.e. 64 bytes, and what you've shown was 128 non-FF bytes, so that was not the problem here.

JW

> If the sector is bigger >11 you must increment setor +4.

Nice catch, thanks for sharing!

JW

PS. For those who might wonder, why:

0693W000007B6i4QAC.png 

Piranha
Chief II

It seems that you fixed it, but just in case... The original post has a bug - wrong register:

// clear the erase action bit
FLASH->SR &= ~FLASH_CR_SER_Msk;

Fasaw.2
Associate

That approach you're jogging Hall-primarily based set of rules as you can read. Could you please offer details of your configuration? The principal parameters of interest: How many shunts did you enter?