cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-G474RE + HAL_FLASH_Program --> PGSERR+PGAERR bit set

giancarlofi
Associate III

Hi, I'm trying to store some information in flash, I'm attaching the program. The problem arises when I use HAL_FLASH_Program function. Inside the FLASH_WaitLastOperation function (called by HAL_FLASH_Program), the PGSERR+PGAERR bits are set after the write operation. Do you have any ideas about this.?
Thanks in advance

// From datasheet rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf pag. 95
#define ADDR_FLASH_PAGE_127 ((uint32_t)0x0807F800) // Bank 2
void _qSaveConfig() {
HAL_FLASH_Unlock();
uint32_t page = _qGetPage(ADDR_FLASH_PAGE_127);
FLASH_PageErase(page, FLASH_BANK_2);
HAL_FLASH_Lock();
 
/* Check FLASH operation error flags */
uint32_t e = HAL_FLASH_GetError();
if (e != 0u) {
qDebugFatalError("Errore in scrittura flash", e);
}
 
HAL_FLASH_Unlock();
 
// afesConfig == configuration to save
uint32_t sizeDataToWrite = sizeof(afesConfig);
uint64_t dataToWrite[sizeDataToWrite];
memcpy(dataToWrite, afesConfig, sizeDataToWrite);
 
// Scrivi i dati nella memoria flash a blocchi di 8 byte
for (uint32_t i = 0; i < sizeDataToWrite; i += 8) {
HAL_StatusTypeDef e = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,
ADDR_FLASH_PAGE_127 + i, sizeDataToWrite);
if (e != HAL_OK) {
uint32_t ee = HAL_FLASH_GetError();
qDebugFatalError("Errore in scrittura flash", ee);
 
}
}
HAL_FLASH_Lock();
}
 
Error 0xA0=0b10100000
PGSERR+PGAERR
From datasheet rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf pag.133 
line 696 of stm32g4xx_hal_flash.c
 error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
  if (error != 0u)
  {
    /* Save the error code */
    pFlash.ErrorCode |= error;
 
    /* Clear error programming flags */
    __HAL_FLASH_CLEAR_FLAG(error);
 
    return HAL_ERROR;
  }

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
giancarlofi
Associate III

It works now, but I don't know why it didn't work before

void qFlashWrite(struct SensorCalibrationValue aconfig[]/*uint32_t *data*/, uint32_t dataSize) {

static FLASH_EraseInitTypeDef EraseInitStruct;

HAL_FLASH_Unlock();

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);

uint32_t firstPage = _qGetPage(FLASH_USER_START_ADDR);

uint32_t nbOfPages = _qGetPage(FLASH_USER_END_ADDR) - firstPage + 1;

uint32_t pageError = 0;

 

EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;

EraseInitStruct.Banks = FLASH_BANK_2;

EraseInitStruct.Page = firstPage;

EraseInitStruct.NbPages = nbOfPages;

if (HAL_FLASHEx_Erase(&EraseInitStruct, &pageError) != HAL_OK) {

qDebugFatalError("Cancellazione fallita", pageError);

}

 

uint32_t bytesWrited = 0;

uint32_t startAddress = FLASH_USER_START_ADDR;

uint64_t dataChunk = 0;

uint32_t dataToWriteAtTime = sizeof(dataChunk);

void *data = aconfig;

// Avendo cancellato solo una pagina è predisposto per scrivere al massimo

// una pagina, esce prima quando raggiunge la quantità di dati da scrivere!!

while (startAddress < FLASH_USER_END_ADDR) {

memcpy(&dataChunk, data, dataToWriteAtTime);

data += dataToWriteAtTime;

//dataChunk = 0;

if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, startAddress,

dataChunk) == HAL_OK) {

startAddress = startAddress + dataToWriteAtTime;

} else {

qDebugFatalError("Scrittura fallita", HAL_FLASH_GetError());

}

bytesWrited += dataToWriteAtTime;

if(bytesWrited >= dataSize) break;

}

 

HAL_FLASH_Lock();

}

View solution in original post

4 REPLIES 4
giancarlofi
Associate III

The right call is:

for (uint32_t i = 0; i < sizeDataToWrite; i += 8) {
    HAL_StatusTypeDef e = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,
       ADDR_FLASH_PAGE_127 + i, dataToWrite[i]);
    if (e != HAL_OK) {
       uint32_t ee = HAL_FLASH_GetError();
       qDebugFatalError("Errore in scrittura flash", ee);
  }
}

I made a mistake in writing the post

You don't say which version of the Cube_G4xx library you are using, but may not matter.  In my last G4xx project (a few years ago, CubeG4 version 1.2), I had to explicitly clear all error flags before every call to HAL_FLASH_Program(), something like this:

HAL_FLASH_Unlock();
for ( ..... ) {
   __HAL_FLASH_CLEAR_FLAG( FLASH_FLAG_ALL_ERRORS );
   sts = HAL_FLASH_Program( ... );
   if ( sts != HAL_OK ) {
      // report error
   }
}
HAL_FLASH_Lock();

Not the most satisfying answer, but it worked.

thanks for the suggestion, unfortunately it doesn't work, I will rewrite the code in another way

giancarlofi
Associate III

It works now, but I don't know why it didn't work before

void qFlashWrite(struct SensorCalibrationValue aconfig[]/*uint32_t *data*/, uint32_t dataSize) {

static FLASH_EraseInitTypeDef EraseInitStruct;

HAL_FLASH_Unlock();

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);

uint32_t firstPage = _qGetPage(FLASH_USER_START_ADDR);

uint32_t nbOfPages = _qGetPage(FLASH_USER_END_ADDR) - firstPage + 1;

uint32_t pageError = 0;

 

EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;

EraseInitStruct.Banks = FLASH_BANK_2;

EraseInitStruct.Page = firstPage;

EraseInitStruct.NbPages = nbOfPages;

if (HAL_FLASHEx_Erase(&EraseInitStruct, &pageError) != HAL_OK) {

qDebugFatalError("Cancellazione fallita", pageError);

}

 

uint32_t bytesWrited = 0;

uint32_t startAddress = FLASH_USER_START_ADDR;

uint64_t dataChunk = 0;

uint32_t dataToWriteAtTime = sizeof(dataChunk);

void *data = aconfig;

// Avendo cancellato solo una pagina è predisposto per scrivere al massimo

// una pagina, esce prima quando raggiunge la quantità di dati da scrivere!!

while (startAddress < FLASH_USER_END_ADDR) {

memcpy(&dataChunk, data, dataToWriteAtTime);

data += dataToWriteAtTime;

//dataChunk = 0;

if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, startAddress,

dataChunk) == HAL_OK) {

startAddress = startAddress + dataToWriteAtTime;

} else {

qDebugFatalError("Scrittura fallita", HAL_FLASH_GetError());

}

bytesWrited += dataToWriteAtTime;

if(bytesWrited >= dataSize) break;

}

 

HAL_FLASH_Lock();

}