Skip to main content
Pilous Droip
Senior
January 12, 2021
Question

Erase stm32f427 from sector 5 to sector 23

  • January 12, 2021
  • 7 replies
  • 1839 views

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.

This topic has been closed for replies.

7 replies

waclawek.jan
Super User
January 12, 2021

This is probably ART's Data Cache.

JW

Tesla DeLorean
Guru
January 12, 2021

Flush any pending error/status when starting out.

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

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?

waclawek.jan
Super User
January 13, 2021

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

Pilous Droip
Senior
January 13, 2021

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.

waclawek.jan
Super User
January 13, 2021

> 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
Principal III
January 13, 2021

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
Visitor II
July 8, 2021

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?