cancel
Showing results for 
Search instead for 
Did you mean: 

PGAERR error on every second Flash programming attempt (STM32L496)

hzoli
Associate II

Hello,

I am trying to use this code to save a 332 byte (83 double word) long data to the STM32L496 flash memory. For some unknown reason, every second time I call the function, I encounter a PGAERR. The third time it works fine, but the fourth time it fails again, and so on.

#define FP_ADDRESS 0x080FF000
#define FP_PAGE    510

void Diag_SavePVD()
{
	__disable_irq();

	/* 0. Erase error flags */
	if (FLASH->SR & (FLASH_SR_PGSERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR))
	    FLASH->SR |=(FLASH_SR_PGSERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR);

	/* 1. Flash Unlock */
	FLASH->KEYR = 0x45670123;
	FLASH->KEYR = 0xCDEF89AB;

	/* 2. Flash page erase */
	while (FLASH->SR & FLASH_SR_BSY);

	FLASH->CR &= ~FLASH_CR_PG;
	FLASH->CR |= FLASH_CR_PER | ((FP_ADDRESS >= 0x08100000) ? FLASH_CR_BKER : 0);

	FLASH->CR &= ~FLASH_CR_PNB_Msk;
	FLASH->CR |= (FP_PAGE << FLASH_CR_PNB_Pos);
	FLASH->CR |= FLASH_CR_STRT;

	while (FLASH->SR & FLASH_SR_BSY);
	FLASH->CR &= ~FLASH_CR_PER;

	/* 3. Flash programming */
	FLASH->CR |= FLASH_CR_PG;

	register __IO uint32_t * dst = (__IO uint32_t*)FP_ADDRESS,
			       * src=(__IO uint32_t*)&PortData.PVD;

	for (register uint32_t size = sizeof(PortData.PVD) / sizeof(uint32_t), c = 0; size--;)
	{
		while (FLASH->SR & FLASH_SR_BSY);
		printf("Write cycle %u: %Xh (%p->%p)\r\n", ++c, FLASH->SR, src, dst);
		*dst++ = *src++;
	}

	while (FLASH->SR & FLASH_SR_BSY);
	FLASH->CR &=~FLASH_CR_PG;

	/* 4. Flash lock */
	FLASH->CR |= FLASH_CR_LOCK;

	__enable_irq();
}

 

Console output:

First run:
Write cycle 1: 0h (0x20004192->0x80ff000)
Write cycle 2: 0h (0x20004196->0x80ff004)
Write cycle 3: 0h (0x2000419a->0x80ff008)
Write cycle 4: 0h (0x2000419e->0x80ff00c)
...
Second run:
Write cycle 1: 0h (0x20004192->0x80ff000)
Write cycle 2: 20h (0x20004196->0x80ff004)
Write cycle 3: A0h (0x2000419a->0x80ff008)
Write cycle 4: A0h (0x2000419e->0x80ff00c)
...
Third run:
Write cycle 1: 0h (0x20004192->0x80ff000)
Write cycle 2: 0h (0x20004196->0x80ff004)
Write cycle 3: 0h (0x2000419a->0x80ff008)
Write cycle 4: 0h (0x2000419e->0x80ff00c)

 

Thank you for your help.

2 REPLIES 2
TDK
Guru

See here for an example of how to write to flash:

STM32CubeL4/Projects/NUCLEO-L452RE/Examples/FLASH/FLASH_EraseProgram/Src/main.c at 874612f28ce541e585f253cdcfd434dd8eb94914 · STMicroelectronics/STM32CubeL4

If you feel a post has answered your question, please click "Accept as Solution".

> 332 byte (83 double word) 

A double word is a uint64_t, and 332 bytes is 41.5 of them.

TDK_0-1743280699245.png

 

TDK_0-1743280853585.png

 

If you feel a post has answered your question, please click "Accept as Solution".