342 lines
10 KiB
C
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>© 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****/
|