cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F401 HAL_FLASH_Program not working

SGasp.1
Senior

Hi community..

I have the following code :

bool FLASH_WriteDoubleWord(uint32_t flashAddress, uint64_t Data)
{
 
	FLASH_Unlock();
	/*clear some flag*/
	 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
 
	//FLASH_Erase_Sector(2, 2);
	 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
 
	/* Program the user Flash area word by word */
	if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)&flashAddress, Data) != HAL_OK)
	{
		FLASH_Lock();
		return false;
	}
 
	FLASH_Lock();
 
	return true;
}

where

static uint32_t     address_test = 0x08008000;
static uint64_t     data_test    = 0xAAAAAAAA;

I don't understand why the erase part is working instead HAL_FLASH_Program it is not writing the data in the expected address.

Can you please tell me why in your opinion?

Thanks a lot.

Simone

14 REPLIES 14
Imen.D
ST Employee

Hello @SGasp.1​ ,

The reference manual says:  

The write access type (byte, half-word, word or double word) must correspond to the type of parallelism chosen (x8, x16, x32 or x64).

If not, the write operation is not performed and a program parallelism error flag (PGPERR) is set in the FLASH_SR register.

So, check if there is an error with the FLASH_SR register prior to calling HAL_FLASHEx_Erase.

Hope my answer helped you! and please keep us informed about your progress on this issue.

When your question is answered, please close this topic by choosing Select as Best. This will help other users find that answer faster.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
TDK
Guru

FLASH_Erase_Sector is not meant to be called directly. Use HAL_FLASHEx_Erase instead.

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

Hi TDK ... the instruction that is not working it is the following ..

HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)&flashAddress, Data) != HAL_OK)

Don't want the address of parameter variable. Need to pass the address as a uint32_t

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
SGasp.1
Senior

Can you provide a working example Tesla ?

Thanks a lot .

This is the function that I am calling

  * @brief  Program byte, halfword, word or double word at a specified address
  * @param  TypeProgram  Indicate the way to program at a specified address.
  *                           This parameter can be a value of @ref FLASH_Type_Program
  * @param  Address  specifies the address to be programmed.
  * @param  Data specifies the data to be programmed
  * 
  * @retval HAL_StatusTypeDef HAL Status
  */
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
{
  HAL_StatusTypeDef status = HAL_ERROR;
  
  /* Process Locked */
  __HAL_LOCK(&pFlash);
  
  /* Check the parameters */
  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
  
  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
  
  if(status == HAL_OK)
  {
    if(TypeProgram == FLASH_TYPEPROGRAM_BYTE)
    {
      /*Program byte (8-bit) at a specified address.*/
      FLASH_Program_Byte(Address, (uint8_t) Data);
    }
    else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
    {
      /*Program halfword (16-bit) at a specified address.*/
      FLASH_Program_HalfWord(Address, (uint16_t) Data);
    }
    else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
    {
      /*Program word (32-bit) at a specified address.*/
      FLASH_Program_Word(Address, (uint32_t) Data);
    }
    else
    {
      /*Program double word (64-bit) at a specified address.*/
      FLASH_Program_DoubleWord(Address, Data);
    }
    
    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
    
    /* If the program operation is completed, disable the PG Bit */
    FLASH->CR &= (~FLASH_CR_PG);  
  }
  
  /* Process Unlocked */
  __HAL_UNLOCK(&pFlash);
  
  return status;
}

Simone

SGasp.1
Senior

I changed the code in this way ...

uint64_t          Data = 1000;
uint32_t        	address_test = 0x08008090;
 
FLASH_WriteDoubleWord(address_test , Data);
 
bool FLASH_WriteDoubleWord(uint32_t flashAddress, uint64_t Data)
{
 
	FLASH_Unlock();
	/*clear some flag*/
 
	FLASH_EraseSectors(2, 1);       /*working*/
 
	/* Program the user Flash area word by word */
	if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flashAddress, Data) != HAL_OK)   /*not working*/
	{
		FLASH_Lock();
		return false;
	}
 
	FLASH_Lock();
 
	return true;
}

Nothing to do...

Please help

Without the ampersand '&'​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I tried to remove but nothing to do

Well it is surely not the address of the variable. Is the function returning an error? Is the ART still caching it? Print out the address passed, print out the flags status.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..