2023-02-19 11:01 AM
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();
}
}
2023-02-19 03:37 PM
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;
}