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(); }
View more

 

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".