2021-01-12 10:27 AM
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.
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.
2021-01-12 12:34 PM
This is probably ART's Data Cache.
JW
2021-01-12 01:33 PM
Flush any pending error/status when starting out.
2021-01-12 09:45 PM
I modificated function:
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?
2021-01-13 04:23 AM
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.
2021-01-13 05:40 AM
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
2021-01-13 05:44 AM
> If the sector is bigger >11 you must increment setor +4.
Nice catch, thanks for sharing!
JW
PS. For those who might wonder, why:
2021-01-13 06:17 AM
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;
2021-07-08 11:56 AM
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?