Files

342 lines
10 KiB
C

/**
******************************************************************************
* @file STM32F4xx_IAP/src/flash_if.c
* @author MCD Application Team
* @version V1.0.0
* @date 10-October-2011
* @brief This file provides all the memory related operation functions.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/** @addtogroup STM32F4xx_IAP
* @{
*/
/* Includes ------------------------------------------------------------------*/
#include "flash_if.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
FW_INFO fwinfo;
/* Private function prototypes -----------------------------------------------*/
static uint32_t GetSector(uint32_t Address);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Unlocks Flash for write access
* @param None
* @retval None
*/
void FLASH_If_Init(void)
{
FLASH_Unlock();
/* Clear pending flags (if any) */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
}
/**
* @brief This function does an erase of all user flash area
* @param StartSector: start of user flash area
* @retval 0: user flash area successfully erased
* 1: error occurred
*/
uint32_t FLASH_If_Erase(uint32_t StartSector)
{
uint32_t UserStartSector = FLASH_Sector_1, i = 0;
/* init flash */
FLASH_If_Init();
/* Get the sector where start the user flash area */
UserStartSector = GetSector(mBMS_FW_ADDRESS);
for(i = UserStartSector; i <= FLASH_Sector_11; i += 8)
{
/* Reload IWDG counter */
IWDG_ReloadCounter();
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (FLASH_EraseSector(i, VoltageRange_3) != FLASH_COMPLETE)
{
/* Error occurred while page erase */
return (1);
}
}
return (0);
}
/**
* @brief This function does an erase of all user flash area
* @param StartSector: start of user flash area
* @retval 0: user flash area successfully erased
* 1: error occurred
*/
uint32_t FLASH_If_SingleSectorErase(uint32_t Sector)
{
uint32_t UserSector;
/* init flash */
FLASH_If_Init();
/* Get the sector where start the user flash area */
UserSector = GetSector(Sector);
/* Reload IWDG counter */
IWDG_ReloadCounter();
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (FLASH_EraseSector(UserSector, VoltageRange_3) != FLASH_COMPLETE)
{
/* Error occurred while page erase */
return (1);
}
return (0);
}
/**
* @brief This function does an erase of all user flash area
* @param StartSector: start of user flash area
* @retval 0: user flash area successfully erased
* 1: error occurred
*/
uint32_t FLASH_If_SectorErase(uint32_t StartSector, uint32_t EndSector)
{
uint32_t UserStartSector, UserEndSector, i = 0;
/* Get the sector where start the user flash area */
UserStartSector = GetSector(StartSector);
UserEndSector = GetSector(EndSector);
for(i = UserStartSector; i <= UserEndSector; i += 8)
{
/* Reload IWDG counter */
IWDG_ReloadCounter();
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (FLASH_EraseSector(i, VoltageRange_3) != FLASH_COMPLETE)
{
/* Error occurred while page erase */
return (1);
}
}
return (0);
}
/**
* @brief This function writes a data buffer in flash (data are 32-bit aligned).
* @note After writing data buffer, the flash content is checked.
* @param FlashAddress: start address for writing data buffer
* @param Data: pointer on data buffer
* @param DataLength: length of data buffer (unit is 32-bit word)
* @retval 0: Data successfully written to Flash memory
* 1: Error occurred while writing data in Flash memory
* 2: Written Data in flash memory is different from expected one
*/
uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data ,uint32_t DataLength)
{
uint32_t i = 0;
for (i = 0; (i < DataLength) && (*FlashAddress <= (mBMS_FW_END_ADDRESS - 4)); i++)
{
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (FLASH_ProgramWord(*FlashAddress, *(uint32_t*)(Data + i)) == FLASH_COMPLETE)
{
/* Check the written value */
if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data + i))
{
/* Flash content doesn't match SRAM content */
return (2);
}
/* Increment FLASH destination address */
*FlashAddress += 4;
}
else
{
/* Error occurred while writing data in Flash memory */
return (1);
}
}
return (0);
}
/**
* @brief This function writes a data buffer in flash (data are 32-bit aligned).
* @note After writing data buffer, the flash content is checked.
* @param FlashAddress: start address for writing data buffer
* @param Data: pointer on data buffer
* @param DataLength: length of data buffer (unit is 32-bit word)
* @retval 0: Data successfully written to Flash memory
* 1: Error occurred while writing data in Flash memory
* 2: Written Data in flash memory is different from expected one
*/
uint32_t FLASH_If_WriteA(__IO uint32_t* FlashAddress, uint32_t* Data, uint32_t DataLength)
{
uint32_t i = 0;
for (i = 0; i < DataLength; i++) {
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (FLASH_ProgramWord(*FlashAddress, *(uint32_t*)(Data + i)) == FLASH_COMPLETE) {
/* Check the written value */
if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data + i)) {
/* Flash content doesn't match SRAM content */
return (2);
}
/* Increment FLASH destination address */
*FlashAddress += 4;
} else {
/* Error occurred while writing data in Flash memory */
return (1);
}
}
return (0);
}
/**
* @brief Returns the write protection status of user flash area.
* @param None
* @retval 0: No write protected sectors inside the user flash area
* 1: Some sectors inside the user flash area are write protected
*/
uint16_t FLASH_If_GetWriteProtectionStatus(void)
{
uint32_t UserStartSector = FLASH_Sector_1;
/* Get the sector where start the user flash area */
UserStartSector = GetSector(mBMS_FW_ADDRESS);
/* Check if there are write protected sectors inside the user flash area */
if ((FLASH_OB_GetWRP() >> (UserStartSector/8)) == (0xFFF >> (UserStartSector/8)))
{ /* No write protected sectors inside the user flash area */
return 1;
}
else
{ /* Some sectors inside the user flash area are write protected */
return 0;
}
}
/**
* @brief Disables the write protection of user flash area.
* @param None
* @retval 1: Write Protection successfully disabled
* 2: Error: Flash write unprotection failed
*/
uint32_t FLASH_If_DisableWriteProtection(void)
{
__IO uint32_t UserStartSector = FLASH_Sector_1, UserWrpSectors = OB_WRP_Sector_1;
/* Get the sector where start the user flash area */
UserStartSector = GetSector(mBMS_FW_ADDRESS);
/* Mark all sectors inside the user flash area as non protected */
UserWrpSectors = 0xFFF-((1 << (UserStartSector/8))-1);
/* Unlock the Option Bytes */
FLASH_OB_Unlock();
/* Disable the write protection for all sectors inside the user flash area */
FLASH_OB_WRPConfig(UserWrpSectors, DISABLE);
/* Start the Option Bytes programming process. */
if (FLASH_OB_Launch() != FLASH_COMPLETE)
{
/* Error: Flash write unprotection failed */
return (2);
}
/* Write Protection successfully disabled */
return (1);
}
/**
* @brief Gets the sector of a given address
* @param Address: Flash address
* @retval The sector of a given address
*/
static uint32_t GetSector(uint32_t Address)
{
uint32_t sector = 0;
if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
{
sector = FLASH_Sector_0;
}
else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
{
sector = FLASH_Sector_1;
}
else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
{
sector = FLASH_Sector_2;
}
else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
{
sector = FLASH_Sector_3;
}
else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
{
sector = FLASH_Sector_4;
}
else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
{
sector = FLASH_Sector_5;
}
else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
{
sector = FLASH_Sector_6;
}
else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
{
sector = FLASH_Sector_7;
}
else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
{
sector = FLASH_Sector_8;
}
else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
{
sector = FLASH_Sector_9;
}
else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
{
sector = FLASH_Sector_10;
}
else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))*/
{
sector = FLASH_Sector_11;
}
return sector;
}
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/