cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L Flash HalfPageProgram problem

martin2399
Associate II
Posted on April 18, 2015 at 23:00

Hi,

I am not able to program the flash of a STM32L151RC using ''half page'' programming.

Normal programming (word by word) works fine.

I have tried it using the 2 latest GCC compilers (4.8.4), and I have tried with the 2 latest HAL drivers (1.1.0 and 1.1.1).

The code below stops working when the 32 words are being written to flash. The debugger stops working. When running the code without a debugges, it also doesn't work.

Am I the only one with this observation?

Best regards

Martin

HAL_FLASH_Unlock();

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR);

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_SIZERR);

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERRUSR);

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_RDERR);

uint32 data[32] = { 0 };

if (HAL_FLASHEx_HalfPageProgram(0x08004000, data) == HAL_OK)

{

// Success

}

else

{

// Error

}

#stm32l-hal-driver-flash-write #iap-flash-half-page-program
7 REPLIES 7
kobus
Associate II
Posted on January 12, 2016 at 23:22

I ran into a similar issue while developing a IAP bootloader for a stm32L1 device. I was modifying an existing bootloader for an F1 device, and found that on the L1 device the flash writes took far too long in word program mode. I tried the HAL_FLASHEx_HalfPageProgram function, but it only seemed to crash.

As I found, this is because the hal library  __ramfunc macro (for gcc) tries to place the function in a memory section called '.RamFunc' which does not exist in the standard linker script for the stm32. I modified my linker script to include a .Ramfunc section in the .data block, and it now works fine.

Hope this helps someone

anthony239955_st
Associate II
Posted on June 27, 2016 at 09:12

Hi, 

I am also having some issues with using HAL_FLASHEx_HalfPageProgram()

I have my bootloader and my application in Memory bank1, and my downloaded image in memory bank 2. 

In bootloader I am trying to write in memory bank 1 (application) , the data located in memory bank 2 (downloader image).

but this process is not working. I am constantly having a PGAERR error. 

This is the code: numBytes = 237568, address=0x08006000

if (((numBytes % 128) == 0) && ((address % 0x80) == 0))

{

                uint32_t* pDataByte = (uint32_t*)pDataToWrite;

                TerminalSend_Str_NL(''Writing half page'');

                // Half Page flash write is 128 bytes (and in multiple of 128-bytes)

                if (HAL_FLASHEx_HalfPageProgram(address, (uint32_t*) pDataByte) != HAL_OK)

                {

                    TerminalSend_Str_Hexu32_NL(''HAL Flash Half Page Write Error: '',     HAL_FLASH_GetError());

                }

}

And my linker file: 

/* Initialized data sections goes into RAM, load LMA copy after code */

  .data : 

  {

    . = ALIGN(4);

    _sdata = .;        /* create a global symbol at data start */

    *(.data)           /* .data sections */

    *(.data*)          /* .data* sections */

    *(.RamFunc)        /* .RamFunc sections */

    . = ALIGN(4);

    _edata = .;        /* define a global symbol at data end */

  } >RAM AT> FLASH

Do you have any idea what could be wrong?

Regards,

B.

Posted on December 10, 2016 at 05:32

,

I have the exact same problem.   I'm using Ramfunc properly.  I can avoid the PGAERR if I only write 8 bytes, e.g.

/* Write one half page directly with 32 different words */

while(count < 2) // was 32

But not very satisfactory. 🙂

Did you solve this problem?  I'm on an STM32L151xE.

Thanks,

G.

Nesrine M_O
Lead II
Posted on January 06, 2017 at 09:50

Hi,

Could you please try to update the HAL_FLASHEx_HalfPageProgram() function as below:

/* Disable all IRQs */
__disable_irq();
/* Write one half page directly with 32 different words */
while(count < 32)
{
*(__IO uint32_t*) ((uint32_t)(Address + (4 * count))) = *pBuffer;
pBuffer++;
count ++;
}
/* Wait for last operation to be completed */ 
status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
/* Enable IRQs */
__enable_irq();�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Please try with this update, and tell us about the result.

-Nesrine-

Ifmy suggestanswers your question, please mark it as correct.

Posted on January 06, 2017 at 19:51

You've added disable/enable_irq()... yes, I think that was one of my problems. Surprisingly in the voluminous but mostly useless boilerplate documentation, no mention or reminder about IRQs in any of the 3 stm32l1xx_hal_flash_*.c files.

I see you've maintained ridiculous coding convention of commenting on a properly named function. The useless verbosity is a hindrance to readability. A comment that says 'disallow interrupts so we don't cause a flash wait-state resulting in a PGAERR' would be ideal. And this original comment:

/* Write one half page directly with 32 different words */

So one is not allowed to write 32 identical words? Where's the check for that? 🙂

Posted on January 27, 2017 at 11:29

The STM32L0 library does include interrupt handling:

__RAM_FUNC HAL_FLASHEx_HalfPageProgram(uint32_t Address, uint32_t *pBuffer)

{

uint32_t count;

HAL_StatusTypeDef status;

/* Wait for last operation to be completed */

status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);

if(status == HAL_OK)

{

/* Proceed to program the new half page */

SET_BIT(FLASH->PECR, FLASH_PECR_FPRG);

SET_BIT(FLASH->PECR, FLASH_PECR_PROG);

count = 0U;

/* Write one half page,

Address doesn't need to be increased */

/* Disable all IRQs */

__disable_irq();

while(count < 16U)

{

*(__IO uint32_t*) Address = *pBuffer;

pBuffer++;

count++;

}

/* Enable IRQs */

__enable_irq();

/* Wait for last operation to be completed */

status = FLASHRAM_WaitForLastOperation(FLASH_TIMEOUT_VALUE);

/* If the write operation is completed, disable the PROG and FPRG bits */

CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);

CLEAR_BIT(FLASH->PECR, FLASH_PECR_FPRG);

}

/* Return the write status */

return status;

}
Posted on January 27, 2017 at 16:45

Lucky you... the code I inherited does not have this.

* @file stm32l1xx_hal_flash_ramfunc.c

* @author MCD Application Team

* @version V1.1.3

* @date 04-March-2016

* @brief FLASH RAMFUNC driver.