cancel
Showing results for 
Search instead for 
Did you mean: 

How to write doublewords to flash on an STM32F411RE

ELeyl.1
Associate II

I could get HAL_FLASH_Program to write WORDS, as soon as I moved to FLASH_TYPEPROGRAM_DOUBLEWORD the last error returned is alwasy PGA | PGS flags in the SR. PGA = alignment, PGS = sequence. I referred to every internet article I could to figure out the problem.

AFAIK, I have done everything correctly. There seems to be a problem with trying to write to FLASH on a 32f411RE. Worked hard to figure it out, I think there is something wrong with the HAL libary, or at least how I am using it. Here is my code:

#define SECTOR 7

#define ADDRESS 0x08060000

 uint32_t lastError = 0;

 uint64_t valueToWrite = ~0ULL;

 uint64_t valueToRead = 0;

 HAL_StatusTypeDef status = HAL_ERROR;

 valueToRead = * ( uint64_t * ) ADDRESS;

 if ( valueToRead == ~0ULL )

 {

FLASH_EraseInitTypeDef pEraseInit = { 0 };

pEraseInit.TypeErase = TYPEERASE_SECTORS;

pEraseInit.Sector = FLASH_SECTOR_7;

pEraseInit.NbSectors = 1;

pEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3;

uint32_t SectorError = 0;

do

{

HAL_FLASH_Unlock();

status = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);

HAL_FLASH_Lock();

valueToRead = * ( uint64_t * ) ADDRESS;

} while( (status !=HAL_OK) || (SectorError != ~0UL ) || ( valueToRead != ~0ULL ) );

HAL_FLASH_Unlock();

status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, ADDRESS, valueToWrite );

HAL_FLASH_Lock();

lastError = 0;

if ( status != HAL_OK )

{

lastError = HAL_FLASH_GetError();

}

}

1 REPLY 1
ELeyl.1
Associate II

https://community.st.com/s/question/0D50X0000AAH2sDSQT/error-writing-64-bit-in-flash

/**

 * @brief Program a double word (64-bit) at a specified address.

 * @note  This function must be used when the device voltage range is from

 *     2.7V to 3.6V and Vpp in the range 7V to 9V.

 *

 * @note  If an erase and a program operations are requested simultaneously,   

 *     the erase operation is performed before the program one.

 *  

 * @param Address specifies the address to be programmed.

 * @param Data specifies the data to be programmed.

 * @retval None

 */

static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)

{

 /* Check the parameters */

 assert_param(IS_FLASH_ADDRESS(Address));

  

 /* If the previous operation is completed, proceed to program the new data */

 CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);

// FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD;

 FLASH->CR |= FLASH_PSIZE_WORD; // We are not writing one 64 bit word, but two 32 bit words

 FLASH->CR |= FLASH_CR_PG;

 /* Program first word */

 *(__IO uint32_t*)Address = (uint32_t)Data;

 /* Barrier to ensure programming is performed in 2 steps, in right order

  (independently of compiler optimization behavior) */

 __ISB();

 /* Program second word */

 *(__IO uint32_t*)(Address+4) = (uint32_t)(Data >> 32);

// *(__IO uint64_t * ) Address = Data;

}