Skip to main content
Explorer II
March 29, 2025
Question

PGAERR error on every second Flash programming attempt (STM32L496)

  • March 29, 2025
  • 1 reply
  • 447 views

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.

    This topic has been closed for replies.

    1 reply

    Super User
    March 29, 2025
    Super User
    March 29, 2025

    > 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