/******************************************************************************* * Function Name : FLASH_If_Erase * Description : Erase sector * Input : None * Output : None * Return : None *******************************************************************************/ uint16_t FLASH_If_Erase(uint32_t Add) { /* Unlock the internal flash */ FLASH_Unlock(); FLASH_ClearFlags(); #if defined (STM32F2XX) || defined (STM32F4XX) /* Disable sector write protection if it's already protected */ uint16_t OB_WRP_Sector = FLASH_SectorToWriteProtect(FLASH_INTERNAL, Add); FLASH_WriteProtection_Disable(OB_WRP_Sector); /* Check which sector has to be erased */ uint16_t FLASH_Sector = FLASH_SectorToErase(FLASH_INTERNAL, Add); FLASH_Status status = FLASH_EraseSector(FLASH_Sector, VoltageRange_3); #elif defined(STM32F10X_CL) /* Call the standard Flash erase function */ FLASH_ErasePage(Add); #endif /* STM32F2XX */ /* Lock the internal flash */ FLASH_Lock(); if (status != FLASH_COMPLETE) return MAL_FAIL; return MAL_OK; }
/** * @brief FLASH_If_Write * Memory write routine. * @param Add: Address to be written to. * @param Len: Number of data to be written (in bytes). * @retval MAL_OK if operation is successeful, MAL_FAIL else. */ uint16_t FLASH_If_Write(uint32_t Add, uint32_t Len) { uint32_t idx = 0; if (Len & 0x3) /* Not an aligned data */ { for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++) { MAL_Buffer[idx] = 0xFF; } } /* Unlock the internal flash */ FLASH_Unlock(); FLASH_ClearFlags(); /* Data received are Word multiple */ FLASH_Status status = FLASH_COMPLETE; for (idx = 0; idx < Len && status == FLASH_COMPLETE; idx = idx + 4) { status = FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx)); Add += 4; } /* Lock the internal flash */ FLASH_Lock(); if (status != FLASH_COMPLETE) return MAL_FAIL; return MAL_OK; }
/** * @brief Writes/updates variable data in EEPROM. * @param EepromAddress: Variable virtual address * @param EepromData: 16 bit data to be written * @retval Success or error status: * - FLASH_COMPLETE: on success * - PAGE_FULL: if valid page is full * - NO_VALID_PAGE: if no valid page was found * - Flash error code: on write Flash error */ static uint16_t EEPROM_WriteVariable(uint16_t EepromAddress, uint16_t EepromData) { uint16_t Status = 0; /* Unlock the Flash Program Erase controller */ FLASH_Unlock(); /* Calling this is here is critical on STM32F2 Devices Else Flash Operation Fails */ FLASH_ClearFlags(); /* Write the variable virtual address and value in the EEPROM */ Status = EEPROM_VerifyPageFullWriteVariable(EepromAddress, EepromData); /* In case the EEPROM active page is full */ if (Status == PAGE_FULL) { /* Perform Page transfer */ Status = EEPROM_PageTransfer(EepromAddress, EepromData); } /* Return last operation status */ return Status; }
/** * @brief Restore the pages to a known good state in case of page's status * corruption after a power loss. * @param None. * @retval - Flash error code: on write Flash error * - FLASH_COMPLETE: on success */ static uint16_t EEPROM_Init(void) { uint16_t PageStatus0 = 6, PageStatus1 = 6; uint16_t virtualAddress = 0; uint16_t EepromStatus = 0, ReadStatus = 0; int16_t x = -1; uint16_t FlashStatus; uint16_t EepromDataVar = 0; /* Calling this is here is critical on STM32F2 Devices Else Flash Operation Fails */ FLASH_ClearFlags(); /* Get Page0 status */ PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS); /* Get Page1 status */ PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS); /* Check for invalid header states and repair if necessary */ switch (PageStatus0) { case ERASED: if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */ { /* Normal valid state -> nothing to do */ } else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */ { /* Erase Page0 */ FlashStatus = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE); /* If erase operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Mark Page1 as valid */ FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } } else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */ { /* Erase both Page0 and Page1 and set Page0 as valid page */ FlashStatus = EEPROM_Format(); /* If erase/program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } } break; case RECEIVE_DATA: if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */ { /* Transfer data from Page1 to Page0 */ for (virtualAddress = 0; virtualAddress < EEPROM_SIZE; virtualAddress++) { if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == virtualAddress) { x = virtualAddress; } if (virtualAddress != x) { /* Read the last variables' updates */ ReadStatus = EEPROM_ReadVariable(virtualAddress, &EepromDataVar); /* In case variable corresponding to the virtual address was found */ if (ReadStatus != 0x1) { /* Transfer the variable to the Page0 */ EepromStatus = EEPROM_VerifyPageFullWriteVariable(virtualAddress, EepromDataVar); /* If program operation was failed, a Flash error code is returned */ if (EepromStatus != FLASH_COMPLETE) { return EepromStatus; } } } } /* Mark Page0 as valid */ FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Erase Page1 */ FlashStatus = FLASH_EraseSector(PAGE1_ID, VOLTAGE_RANGE); /* If erase operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } } else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */ { /* Erase Page1 */ FlashStatus = FLASH_EraseSector(PAGE1_ID, VOLTAGE_RANGE); /* If erase operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Mark Page0 as valid */ FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } } else /* Invalid state -> format eeprom */ { /* Erase both Page0 and Page1 and set Page0 as valid page */ FlashStatus = EEPROM_Format(); /* If erase/program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } } break; case VALID_PAGE: if (PageStatus1 == VALID_PAGE) /* Harmless invalid state -> pick one page and format the other */ { /* Erase Page0 */ FlashStatus = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE); /* If erase/program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } } else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */ { /* Normal valid state -> nothing to do */ } else /* Page0 valid, Page1 receive */ { /* Transfer data from Page0 to Page1 */ for (virtualAddress = 0; virtualAddress < EEPROM_SIZE; virtualAddress++) { if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == virtualAddress) { x = virtualAddress; } if (virtualAddress != x) { /* Read the last variables' updates */ ReadStatus = EEPROM_ReadVariable(virtualAddress, &EepromDataVar); /* In case variable corresponding to the virtual address was found */ if (ReadStatus != 0x1) { /* Transfer the variable to the Page1 */ EepromStatus = EEPROM_VerifyPageFullWriteVariable(virtualAddress, EepromDataVar); /* If program operation was failed, a Flash error code is returned */ if (EepromStatus != FLASH_COMPLETE) { return EepromStatus; } } } } /* Mark Page1 as valid */ FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE); /* If program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } /* Erase Page0 */ FlashStatus = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE); /* If erase operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } } break; default: /* Any other state -> format eeprom */ /* Erase both Page0 and Page1 and set Page0 as valid page */ FlashStatus = EEPROM_Format(); /* If erase/program operation was failed, a Flash error code is returned */ if (FlashStatus != FLASH_COMPLETE) { return FlashStatus; } break; } return FLASH_COMPLETE; }
bool FLASH_EraseMemory(flash_device_t flashDeviceID, uint32_t startAddress, uint32_t length) { uint32_t eraseCounter = 0; uint32_t numPages = 0; if (FLASH_CheckValidAddressRange(flashDeviceID, startAddress, length) != true) { return false; } if (flashDeviceID == FLASH_INTERNAL) { /* Check which sector has to be erased */ uint16_t flashSector = FLASH_SectorToErase(FLASH_INTERNAL, startAddress); if (flashSector > FLASH_Sector_11) { return false; } /* Disable memory write protection if any */ FLASH_WriteProtectMemory(FLASH_INTERNAL, startAddress, length, false); /* Unlock the Flash Program Erase Controller */ FLASH_Unlock(); /* Define the number of Internal Flash pages to be erased */ numPages = FLASH_PagesMask(length, INTERNAL_FLASH_PAGE_SIZE); /* Clear All pending flags */ FLASH_ClearFlags(); /* Erase the Internal Flash pages */ for (eraseCounter = 0; (eraseCounter < numPages); eraseCounter++) { FLASH_Status status = FLASH_EraseSector(flashSector + (8 * eraseCounter), VoltageRange_3); /* If erase operation fails, return Failure */ if (status != FLASH_COMPLETE) { return false; } } /* Locks the FLASH Program Erase Controller */ FLASH_Lock(); return true; } else if (flashDeviceID == FLASH_SERIAL) { #ifdef USE_SERIAL_FLASH /* Initialize SPI Flash */ sFLASH_Init(); /* Define the number of External Flash pages to be erased */ numPages = FLASH_PagesMask(length, sFLASH_PAGESIZE); /* Erase the SPI Flash pages */ for (eraseCounter = 0; (eraseCounter < numPages); eraseCounter++) { sFLASH_EraseSector(startAddress + (sFLASH_PAGESIZE * eraseCounter)); } /* Return Success */ return true; #endif } /* Return Failure */ return false; }