cancel
Showing results for 
Search instead for 
Did you mean: 

FLASH FastProgram allways return PGAERR ...

varga
Associate II
Posted on March 23, 2018 at 16:34

Device STM32L452RE on my HW board with 3V3 Vdd ...

This code is placed in RAM ...

//--- Program

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);

//--- FLASH_Program_Fast

uint8_t

ID;

uint32_t

DstAddr = (FLASH_BASE + Addr) & 0xFFFFFFF8;

SET_BIT(FLASH->

CR

, FLASH_CR_FSTPG);

//--- Program the double word of the row

for

(ID = 0; ID < (32 * 2); ID++)

{

*(

uint32_t

*)(DstAddr) = 0xAABBCCDD;

DstAddr += 4;

}

// Wait for last operation to be completed

while

(READ_BIT(FLASH->

SR

, FLASH_FLAG_BSY)) {};

if

(READ_BIT(FLASH->

SR

, FLASH_FLAG_PGAERR)) LED_BO_Set(

LED_BO_ORANGE

, 1);

Where is error?

#stm32l4-fastprogram
16 REPLIES 16
Posted on March 23, 2018 at 18:19

What address are you writing?

Is the memory erased first?

The mask aligns to 64-bits

You write 64 32-bit words, 256 bytes, 2048-bits

uint8_t variables are not efficient

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 03, 2018 at 15:33

1. FLASH_BASE = 0x08000000, Addr = 0x00040000

2. Yes, page erased (

Checked via STM32 ST-LINK Utility v4.1.0.0)

Dave Jones
Associate III
Posted on April 10, 2018 at 06:48

I'm having this same problem, with this same processor. I'm not running it out of RAM, like the OP.

I successfully wrote a page erase function, following the steps in the reference manual. It works fine with no errors. I also wrote a program double word function, which also works fine with no errors. But when I tried to write a program row function, the PGAERR bit is set, as well as the PGSERR and FASTERR bits (both of which say they will be set if the PGAERR bit is set). The PGAERR says on row programming it will be set if the function changes page during the writing of the 64 words. But that is not happening in my code. 

I am starting the write at address 0x08010800. That is the page that I first erase (page #33). And the address I start at is not only a double word boundary, and a row boundary, it is also a page boundary. So there's no way that writing to the first 64 words of a page should cause an error defined as 'changing page'.

After a few hours of trying various things in my own code, I tried using the HAL function HAL_FLASH_Program(), which is the polling version of their FLASH memory writing functions. I gave it that same address, set the 'TypeProgram' to FLASH_TYPEPROGRAM_FAST_AND_LAST (which means program one row and then stop). I  created a uint64_t array full of zeros and passed that to the function (that's what they use for the data in). I tested the function on return and it failed the return check for HAL_OK. And checking the page in the debugger shows none of it got set to zeros.

So my function (several variations of it) failed, and so did the HAL function to do a row program.

I checked the errata sheet and the only issue with FLASH is that the OPTVERR bit is incorrectly set in this part. I did add the code earlier in my program to clear that bit, as suggested in the errata. It made no difference.

So, if anybody out there has a board with an STM32L452 on it that is able to do a row program, please let us know how you did it.

Posted on April 10, 2018 at 22:07

And I tried this with optimization disabled (easier debugging) and with it optimized for speed. No difference.

There's no reference manual for the L4x2 parts (like there are for L4x1, L4x5, and L4x6), so I'm using the one for the L43x, L44x, L45x, and L46x.

So if anybody has gotten an L4 part to work with row programming ('FASTPG'), I'd love to hear which part and what steps you used. And if you came across the same error and found a solution.

Posted on April 11, 2018 at 07:54

That seems like the right RM for the L452, it specifically calls it out.

Will check the box at the office, none to hand here.

The DEV_ID should be 0x0462

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 11, 2018 at 18:26

I had not checked that before, but just did. Yes, the DEV_ID does read out as 0x0462

Posted on April 12, 2018 at 03:28

I just tried a version where I defined my row programming function as being in RAM. It didn't help. When I run it in debug and stop after the writing should be complete, I still see those same error bits. I'm assuming that it should work when running a debug version. (the page erase and double word write functions worked fine from the debugger)

Posted on April 12, 2018 at 03:51

I found a demo program in the L4 firmware package to do a row write. Both it and the reference manual mention doing a mass erase before running the row write. I certainly hope that isn't a requirement. I don't want to erase all the flash. I want to erase a page and then fill it using 8 row writes rather than 256 double word writes.

Dave Jones
Associate III
Posted on April 12, 2018 at 22:45

One thing I came across today was a comment in a thread talking about the row programming function not executing from RAM because even though HAL defines the function as being in section .RamFunc, there is in fact no section with that name defined in the linker script. I didn't pay attention last night to verify in the debugger if the function was actually running from RAM. I added that section to my linker script (in the initialized RAM area), and verified while debugging that my row write function is in fact executing from RAM. Still doesn't work though.

To try and dig deeper into what is happening I created an array in RAM, and before each of the word writes in my function I read the FLASH->CR and FLASH->SR registers and stuck them into the array. Then I stop the debugger near the end of the function and look at the contents of that array.

What I found is that throughout the loop the CR didn't change (as would be expected), and that the FSTPG bit is set and LOCK is clear, and no other unexpected bits are set wrong.

Before the first word is written, the SR register is clear. No bits set. After the first word is written the PGSERR bit is set, all other bits are clear. After the second word is written the PGSERR, FASTERR, and PGAERR bits are all set (the rest are clear). That remains the same for the rest of the loop and afterwards when I reach the breakpoint at the end of the function.

The ref manual says that PGSERR is set if a write access to flash is performed without PG or FSTPG set. (but FSTPG is set, according to the CR register reading in my array). PGSERR can also be set if PROGERR, SIZERR, PGAERR, MISSERR, or FASTERR are set. But after that first word write, only the PGSERR bit is set. Those others are all clear.

After writing the second word, PGSERR, FASTERR, and PGAERR bits are all set. FASTERR says it is set during a fast write if PGAERR, SIZERR, WRPERR, or MISSERR are set. Of those, only the PGAERR is set. So at that point I have to assume that FASTERR and PGSERR are both set because PGAERR is set. (though that still doesn't explain why PGSERR was set by itself after the first word write).

PGAERR says it is set if there is a change of page during Fast programming. But that isn't happening. The first word write is going to 0x8010800, which is the start of a page. Subsequent writes are to words continuing from that point. The pointer used to point at the flash location is defined as __IO uint32_t *, and the debugger is showing it pointing to the next word after the first row (64 words) when the function is done. So the pointer starts out pointing at 0x8010800 and after the loop it is pointing at 0x8010900.

So I do not see how by the time of the second word write the hardware believes that the write was attempted at a different page. Or understand why PGSERR is set by itself after the first word write.