Skip to main content
Explorer II
July 24, 2024
Solved

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

  • July 24, 2024
  • 2 replies
  • 1369 views

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;
  }

 

 

    This topic has been closed for replies.
    Best answer by giancarlofi

    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();

    }

    2 replies

    Explorer II
    July 24, 2024

    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

    Super User
    July 24, 2024

    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.

    Explorer II
    July 25, 2024

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

    giancarlofiAuthorAnswer
    Explorer II
    July 25, 2024

    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();

    }