工具配置
Flash组件是用来管理Flash的,初始化的时候用来分区。BootLoader就放在Pflash里面,FTFC是一个控制Flash操作的控制器,一般不用回调函数。
生成的代码在Generated_Code/Flash.c和Flash.h里面。
EERAMBase其实就是FlexRAM。这块是很厉害的,既能够当做E方来用,掉电记忆,也能当做普通的RAM来用。
/*! @brief Configuration structure flashCfg_0 */
const flash_user_config_t Flash_InitConfig0 = {
.PFlashBase = 0x00000000U, /* Base address of Program Flash block */
.PFlashSize = 0x00100000U, /* Size of Program Flash block */
.DFlashBase = 0x10000000U, /* Base address of Data Flash block */
.EERAMBase = 0x14000000U, /* Base address of FlexRAM block */
/* If using callback, any code reachable from this function must not be placed in a Flash block targeted for a program/erase operation.*/
.CallBack = NULL_CALLBACK
};
接口使用
生成接口在SDK\platform\drivers\src\flash\flash_driver.c里面
FLASH_DRV_Init
这个是一定要用到的,初始化之后才能操作Flash,无论是BootLoader还是Flash模拟E方,都要先初始化一次。
调用的时候要先新建个flash_ssd_config_t类型的对象,进去接收配置信息。
/*FUNCTION*******************************************************************************
*
* Function Name : FLASH_DRV_Init
* Description : Initializes Flash module by reporting the memory configuration via
* SSD configuration structure.
*
* Implements : FLASH_DRV_Init_Activity
*END***********************************************************************************/
status_t FLASH_DRV_Init(const flash_user_config_t * const pUserConf,
flash_ssd_config_t * const pSSDConfig)
{
DEV_ASSERT(pUserConf != NULL);
DEV_ASSERT(pSSDConfig != NULL);
status_t ret = STATUS_SUCCESS;
#if FEATURE_FLS_HAS_FLEX_NVM
uint8_t DEPartitionCode; /* store D/E-Flash Partition Code */
#endif
pSSDConfig->PFlashBase = pUserConf->PFlashBase;
pSSDConfig->PFlashSize = pUserConf->PFlashSize;
pSSDConfig->DFlashBase = pUserConf->DFlashBase;
pSSDConfig->EERAMBase = pUserConf->EERAMBase;
pSSDConfig->CallBack = pUserConf->CallBack;
#if FEATURE_FLS_HAS_FLEX_NVM
/* Temporary solution for FTFC and S32K144 CSEc part */
/* Get DEPART from Flash Configuration Register 1 */
DEPartitionCode = (uint8_t)((SIM->FCFG1 & SIM_FCFG1_DEPART_MASK) >> SIM_FCFG1_DEPART_SHIFT);
/* Get data flash size */
FLASH_DRV_GetDEPartitionCode(pSSDConfig, DEPartitionCode);
if (pSSDConfig->DFlashSize < FEATURE_FLS_DF_BLOCK_SIZE)
{
pSSDConfig->EEESize = FEATURE_FLS_FLEX_RAM_SIZE;
}
else
{
pSSDConfig->EEESize = 0U;
}
#else /* FEATURE_FLS_HAS_FLEX_NVM == 0 */
/* If size of D/E-Flash = 0 */
pSSDConfig->DFlashSize = 0U;
pSSDConfig->EEESize = 0U;
#endif /* End of FEATURE_FLS_HAS_FLEX_NVM */
return ret;
}
FLASH_DRV_GetPFlashProtection
获取PFlash的保护状态。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_GetPFlashProtection
* Description : Retrieves the current P-Flash protection status.
* Considering the time consumption for getting protection is very low and
* even can be ignored. It is not necessary to utilize the Callback function to
* support the time-critical events.
*
* Implements : FLASH_DRV_GetPFlashProtection_Activity
*END**************************************************************************/
void FLASH_DRV_GetPFlashProtection(uint32_t * protectStatus)
{
DEV_ASSERT(protectStatus != NULL);
uint32_t reg0, reg1, reg2, reg3;
reg0 = FTFx_FPROT0;
reg1 = FTFx_FPROT1;
reg2 = FTFx_FPROT2;
reg3 = FTFx_FPROT3;
*protectStatus = (uint32_t)((reg0 << 24U) | (reg1 << 16U) | (reg2 << 8U) | reg3);
}
FLASH_DRV_SetPFlashProtection
设置PFlash的保护状态。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_SetPFlashProtection
* Description : Sets the P-Flash protection to the intended protection status.
* Setting P-Flash protection status is subject to a protection transition
* restriction. If there is a setting violation, it returns an error code
* and the current protection status will not be changed.
*
* Implements : FLASH_DRV_SetPFlashProtection_Activity
*END**************************************************************************/
status_t FLASH_DRV_SetPFlashProtection(uint32_t protectStatus)
{
status_t ret = STATUS_SUCCESS;
uint8_t reg0, reg1, reg2, reg3;
bool flag0, flag1, flag2, flag3;
/* Get register */
reg0 = GET_BIT_24_31(protectStatus);
reg1 = GET_BIT_16_23(protectStatus);
reg2 = GET_BIT_8_15(protectStatus);
reg3 = GET_BIT_0_7(protectStatus);
/* Write to register */
FTFx_FPROT0 = reg0;
FTFx_FPROT1 = reg1;
FTFx_FPROT2 = reg2;
FTFx_FPROT3 = reg3;
/* Compare changes */
flag0 = (FTFx_FPROT0 != reg0);
flag1 = (FTFx_FPROT1 != reg1);
flag2 = (FTFx_FPROT2 != reg2);
flag3 = (FTFx_FPROT3 != reg3);
/* Read the value of FPPROT registers */
if (flag0 || flag1 || flag2 || flag3)
{
ret = STATUS_ERROR;
}
return ret;
}
FLASH_DRV_GetSecurityState
获取安全状态
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_GetSecurityState
* Description : Retrieves the current Flash security status, including
* the security enabling state and the back door key enabling state.
*
* Implements : FLASH_DRV_GetSecurityState_Activity
*END**************************************************************************/
void FLASH_DRV_GetSecurityState(uint8_t * securityState)
{
DEV_ASSERT(securityState != NULL);
/* Store data read from flash register */
uint8_t regValue;
/* Get flash security register value */
regValue = FTFx_FSEC;
/* Check the status of the flash security bits in the security register */
if (FLASH_SECURITY_STATE_UNSECURED == (regValue & FTFx_FSEC_SEC_MASK))
{
/* Flash in unsecured state */
*securityState = FLASH_NOT_SECURE;
}
else
{
/* Flash in secured state
* Check for backdoor key security enable bit
*/
if (0x80U == (regValue & FTFx_FSEC_KEYEN_MASK))
{
/* Backdoor key security enabled */
*securityState = FLASH_SECURE_BACKDOOR_ENABLED;
}
else
{
/* Backdoor key security disabled */
*securityState = FLASH_SECURE_BACKDOOR_DISABLED;
}
}
}
FLASH_DRV_SecurityBypass
解除安全保护
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_SecurityBypass
* Description : Un-secures the device by comparing the user's provided back
* door key with the ones in the Flash Configuration Field. If they are
* matched, the security is released. Otherwise, an error code is returned.
*
* Implements : FLASH_DRV_SecurityBypass_Activity
*END**************************************************************************/
status_t FLASH_DRV_SecurityBypass(const flash_ssd_config_t * pSSDConfig,
const uint8_t * keyBuffer)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(keyBuffer != NULL);
status_t ret; /* Return code variable */
uint32_t temp; /* Temporary variable */
uint8_t i;
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_SECURITY_BY_PASS;
for (i = 0U; i < 8U; i++)
{
temp = FTFx_BASE + i + 0x08U;
*(uint8_t *)temp = keyBuffer[i];
}
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
return ret;
}
FLASH_DRV_EraseAllBlock
擦除所有Flash块,一块512KB,擦完之后会解除安全保护,这里要注意别把自己给擦了。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_EraseAllBlock
* Description : Erases all Flash memory, initializes the FlexRAM, verifies
* all memory contents, and then releases the MCU security.
*
* Implements : FLASH_DRV_EraseAllBlock_Activity
*END**************************************************************************/
status_t FLASH_DRV_EraseAllBlock(const flash_ssd_config_t * pSSDConfig)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret; /* Return code variable */
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_ERASE_ALL_BLOCK;
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
return ret;
}
FLASH_DRV_VerifyAllBlock
检查所有块是不是满足校验级别,一般是BootLoader里面用。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_VerifyAllBlock
* Description : Checks to see if the P-Flash and/or D-Flash, EEPROM
* backup area, and D-Flash IFR have been erased to the specified read
* margin level, if applicable, and releases security if the readout passes.
*
* Implements : FLASH_DRV_VerifyAllBlock_Activity
*END**************************************************************************/
status_t FLASH_DRV_VerifyAllBlock(const flash_ssd_config_t * pSSDConfig,
uint8_t marginLevel)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret; /* Return code variable */
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_VERIFY_ALL_BLOCK;
FTFx_FCCOB1 = marginLevel;
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
return ret;
}
FLASH_DRV_EraseSector
以段(4096字节)为单位来擦除PFlash或者DFlash里面的内容。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_EraseSector
* Description : Erases one or more sectors in P-Flash or D-Flash memory.
* This API always returns STATUS_SUCCESS if size provided by the user is
* zero regardless of the input validation.
*
* Implements : FLASH_DRV_EraseSector_Activity
*END**************************************************************************/
status_t FLASH_DRV_EraseSector(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
uint32_t size)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t sectorSize; /* Size of one sector */
uint32_t temp; /* Temporary variable */
uint32_t tempSize = size; /* Temporary of size variation */
#if FEATURE_FLS_HAS_FLEX_NVM
temp = pSSDConfig->DFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_DF_SECTOR_CMD_ADDRESS_ALIGMENT) == 0U);
dest += 0x800000U - temp;
sectorSize = (uint32_t)FEATURE_FLS_DF_BLOCK_SECTOR_SIZE;
}
else
#endif
{
temp = pSSDConfig->PFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_PF_SECTOR_CMD_ADDRESS_ALIGMENT) == 0U);
dest -= temp;
sectorSize = (uint32_t)FEATURE_FLS_PF_BLOCK_SECTOR_SIZE;
}
else
{
ret = STATUS_ERROR;
tempSize = 0U;
sectorSize = 0U;
}
}
/* Check if the size is sector alignment or not */
if ((tempSize & (sectorSize - 1U)) != 0U)
{
/* Return an error code */
ret = STATUS_ERROR;
}
while ((tempSize > 0U) && (STATUS_SUCCESS == ret))
{
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_ERASE_SECTOR;
FTFx_FCCOB1 = GET_BIT_16_23(dest);
FTFx_FCCOB2 = GET_BIT_8_15(dest);
FTFx_FCCOB3 = GET_BIT_0_7(dest);
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
/* Update size and destination address */
tempSize -= sectorSize;
dest += sectorSize;
}
}
return ret;
}
调用方法
address是擦除的首地址,FEATURE_FLS_PF_BLOCK_SECTOR_SIZE是每个段的长度。
#define FEATURE_FLS_PF_BLOCK_SECTOR_SIZE (4096u)
FLASH_DRV_EraseSector(&flashSSDConfig, address, FEATURE_FLS_PF_BLOCK_SECTOR_SIZE);
FLASH_DRV_VerifySection
检查所有段是不是满足校验级别,一般是BootLoader里面用。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_VerifySection
* Description : Checks if a section of the P-Flash or the D-Flash memory
* is erased to the specified read margin level.
*
* Implements : FLASH_DRV_VerifySection_Activity
*END**************************************************************************/
status_t FLASH_DRV_VerifySection(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
uint16_t number,
uint8_t marginLevel)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t temp;
/* Check if the destination is aligned or not */
#if FEATURE_FLS_HAS_FLEX_NVM
temp = pSSDConfig->DFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_DF_SECTION_CMD_ADDRESS_ALIGMENT) == 0U);
dest += 0x800000U - temp;
}
else
#endif
{
temp = pSSDConfig->PFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_PF_SECTION_CMD_ADDRESS_ALIGMENT) == 0U);
dest -= temp;
}
else
{
ret = STATUS_ERROR;
}
}
if (STATUS_SUCCESS == ret)
{
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_VERIFY_SECTION;
FTFx_FCCOB1 = GET_BIT_16_23(dest);
FTFx_FCCOB2 = GET_BIT_8_15(dest);
FTFx_FCCOB3 = GET_BIT_0_7(dest);
FTFx_FCCOB4 = GET_BIT_8_15(number);
FTFx_FCCOB5 = GET_BIT_0_7(number);
FTFx_FCCOB6 = marginLevel;
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
}
return ret;
}
FLASH_DRV_EraseSuspend
擦除暂停,擦到不对路的时候就会停下来。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_EraseSuspend
* Description : Suspend a current operation of Flash erase sector command.
* This function must be located in RAM memory or different Flash blocks which are
* targeted for writing to avoid the RWW error.
*
* Implements : FLASH_DRV_EraseSuspend_Activity
*END**************************************************************************/
void FLASH_DRV_EraseSuspend(void)
{
uint32_t count = SUSPEND_WAIT_CNT; /* Counter variable */
if ((FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK) == 0U)
{
FTFx_FCNFG |= FTFx_FCNFG_ERSSUSP_MASK;
/* Wait till CCIF bit is set */
while (((FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK) == 0U) && (count > 0U))
{
count--;
}
}
}
FLASH_DRV_EraseResume
擦除恢复,也就是继续擦
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_EraseResume
* Description : Resume a previous suspended operation of Flash erase sector command
* This function must be located in RAM memory or different Flash blocks which are targeted
* for writing to avoid RWW error.
*
* Implements : FLASH_DRV_EraseResume_Activity
*END**************************************************************************/
void FLASH_DRV_EraseResume(void)
{
uint16_t i = 0U; /* Counter variable */
/* Check ERSSUSP bit of the flash configuration register */
if ((FTFx_FCNFG & FTFx_FCNFG_ERSSUSP_MASK) == FTFx_FCNFG_ERSSUSP_MASK)
{
/* Clear CCIF to launch command */
FTFx_FSTAT |= FTFx_FSTAT_CCIF_MASK;
/* Wait for completion of this command */
while ((0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK)) && (i < RESUME_WAIT_CNT))
{
i++;
}
}
}
FLASH_DRV_ReadOnce
读位于PFlash的IFR的64字节
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_ReadOnce
* Description : Read out a reserved 64 byte field located in the P-Flash IFR via given number
* of record. See the corresponding reference manual to get the correct value of this number.
*
* Implements : FLASH_DRV_ReadOnce_Activity
*END**************************************************************************/
status_t FLASH_DRV_ReadOnce(const flash_ssd_config_t * pSSDConfig,
uint8_t recordIndex,
uint8_t * pDataArray)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(pDataArray != NULL);
status_t ret; /* Return code variable */
uint32_t temp; /* Temporary variable */
uint8_t i;
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_READ_ONCE;
FTFx_FCCOB1 = recordIndex;
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
/* Checking for the success of command execution */
if (STATUS_SUCCESS == ret)
{
/* Read the data from the FCCOB registers into the pDataArray */
for (i = 0U; i < FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE; i++)
{
temp = FTFx_BASE + i + 0x08U;
pDataArray[i] = *(uint8_t *)temp;
}
}
}
return ret;
}
FLASH_DRV_ProgramOnce
写位于PFlash的IFR的64字节
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_ProgramOnce
* Description : Program to a reserved 64 byte field located in the
* P-Flash IFR via given number of record. See the corresponding reference manual
* to get correct value of this number.
*
* Implements : FLASH_DRV_ProgramOnce_Activity
*END**************************************************************************/
status_t FLASH_DRV_ProgramOnce(const flash_ssd_config_t * pSSDConfig,
uint8_t recordIndex,
const uint8_t * pDataArray)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(pDataArray != NULL);
status_t ret; /* Return code variable */
uint32_t temp; /* Temporary variable */
uint8_t i;
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_PROGRAM_ONCE;
FTFx_FCCOB1 = recordIndex;
for (i = 0U; i < FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE; i++)
{
temp = FTFx_BASE + i + 0x08U;
*(uint8_t *)temp = pDataArray[i];
}
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
return ret;
}
FLASH_DRV_ReadResource
从Flash读数据
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_ReadResource
* Description : Read data from special purpose memory in Flash memory module
* including P-Flash IFR, swap IFR, D-Flash IFR space and version ID.
*
*END**************************************************************************/
status_t FLASH_DRV_ReadResource(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
uint8_t * pDataArray,
uint8_t resourceSelectCode)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(pDataArray != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t temp;
uint8_t i;
/* Check if the destination is aligned or not */
#if FEATURE_FLS_HAS_FLEX_NVM
temp = pSSDConfig->DFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
{
DEV_ASSERT(dest % FEATURE_FLS_DF_RESOURCE_CMD_ADDRESS_ALIGMENT == 0);
dest += 0x800000U - temp;
}
else
#endif
{
DEV_ASSERT(dest % FEATURE_FLS_PF_RESOURCE_CMD_ADDRESS_ALIGMENT == 0);
temp = pSSDConfig->PFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
{
dest -= temp;
}
else
{
ret = STATUS_ERROR;
}
}
if (ret == STATUS_SUCCESS)
{
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_READ_RESOURCE;
FTFx_FCCOB1 = GET_BIT_16_23(dest);
FTFx_FCCOB2 = GET_BIT_8_15(dest);
FTFx_FCCOB3 = GET_BIT_0_7(dest);
FTFx_RSRC_CODE_REG = resourceSelectCode;
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
if (STATUS_SUCCESS == ret)
{
/* Read the data from the FCCOB registers into the pDataArray */
for (i = 0U; i < FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE; i++)
{
temp = FTFx_BASE + i + 0x08U;
pDataArray[i] = *(uint8_t *)temp;
}
}
}
}
return ret;
}
FLASH_DRV_Program
4个字节的倍数长度写数据,这个在BootLoader里面必然用到。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_Program
* Description : Program 4 consecutive bytes (for program long word command)
* and 8 consecutive bytes (for program phrase command) on P-Flash or D-Flash block.
* This API always returns STATUS_SUCCESS if size provided by user is
* zero regardless of the input validation.
*
* Implements : FLASH_DRV_Program_Activity
*END**************************************************************************/
status_t FLASH_DRV_Program(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
uint32_t size,
const uint8_t * pData)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(pData != NULL);
DEV_ASSERT((dest % FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE) == 0U);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t temp;
uint8_t i;
if ((size & (FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE - 1U)) != 0U)
{
ret = STATUS_ERROR;
}
else
{
#if FEATURE_FLS_HAS_FLEX_NVM
temp = pSSDConfig->DFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
{
dest += 0x800000U - temp;
}
else
#endif
{
temp = pSSDConfig->PFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
{
dest -= temp;
}
else
{
ret = STATUS_ERROR;
}
}
while ((size > 0U) && (STATUS_SUCCESS == ret))
{
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
#if (FEATURE_FLS_DF_BLOCK_WRITE_UNIT_SIZE == FTFx_PHRASE_SIZE)
FTFx_FCCOB0 = FTFx_PROGRAM_PHRASE;
#else
FTFx_FCCOB0 = FTFx_PROGRAM_LONGWORD;
#endif
FTFx_FCCOB1 = GET_BIT_16_23(dest);
FTFx_FCCOB2 = GET_BIT_8_15(dest);
FTFx_FCCOB3 = GET_BIT_0_7(dest);
for (i = 0U; i < FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE; i++)
{
temp = FTFx_BASE + i + 0x08U;
*(uint8_t *)(temp) = pData[i];
}
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
/* Update destination address for next iteration */
dest += FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE;
/* Update size for next iteration */
size -= FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE;
/* Increment the source address by 1 */
pData += FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE;
}
}
}
return ret;
}
FLASH_DRV_ProgramCheck
也是校验写入的程序
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_Program
* Description : Program 4 consecutive bytes (for program long word command)
* and 8 consecutive bytes (for program phrase command) on P-Flash or D-Flash block.
* This API always returns STATUS_SUCCESS if size provided by user is
* zero regardless of the input validation.
*
* Implements : FLASH_DRV_Program_Activity
*END**************************************************************************/
status_t FLASH_DRV_Program(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
uint32_t size,
const uint8_t * pData)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(pData != NULL);
DEV_ASSERT((dest % FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE) == 0U);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t temp;
uint8_t i;
if ((size & (FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE - 1U)) != 0U)
{
ret = STATUS_ERROR;
}
else
{
#if FEATURE_FLS_HAS_FLEX_NVM
temp = pSSDConfig->DFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
{
dest += 0x800000U - temp;
}
else
#endif
{
temp = pSSDConfig->PFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
{
dest -= temp;
}
else
{
ret = STATUS_ERROR;
}
}
while ((size > 0U) && (STATUS_SUCCESS == ret))
{
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
#if (FEATURE_FLS_DF_BLOCK_WRITE_UNIT_SIZE == FTFx_PHRASE_SIZE)
FTFx_FCCOB0 = FTFx_PROGRAM_PHRASE;
#else
FTFx_FCCOB0 = FTFx_PROGRAM_LONGWORD;
#endif
FTFx_FCCOB1 = GET_BIT_16_23(dest);
FTFx_FCCOB2 = GET_BIT_8_15(dest);
FTFx_FCCOB3 = GET_BIT_0_7(dest);
for (i = 0U; i < FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE; i++)
{
temp = FTFx_BASE + i + 0x08U;
*(uint8_t *)(temp) = pData[i];
}
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
/* Update destination address for next iteration */
dest += FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE;
/* Update size for next iteration */
size -= FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE;
/* Increment the source address by 1 */
pData += FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE;
}
}
}
return ret;
}
FLASH_DRV_CheckSum
生成校验码
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_CheckSum
* Description : Performs 32 bit sum of each byte data over a specified Flash
* memory range without carry which provides rapid method for checking data integrity.
* The callback time period of this API is determined via FLASH_CALLBACK_CS macro in the
* flash_driver.h which is used as a counter value for the CallBack() function calling in
* this API. This value can be changed as per the user requirement. User can change this value
* to obtain the maximum permissible callback time period.
* This API always returns STATUS_SUCCESS if size provided by user is zero regardless of the input
* validation.
*
* Implements : FLASH_DRV_CheckSum_Activity
*END**************************************************************************/
status_t FLASH_DRV_CheckSum(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
uint32_t size,
uint32_t * pSum)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(pSum != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t counter = 0U; /* Counter for callback operation */
uint32_t data; /* Data read from Flash address */
uint32_t endAddress; /* PFlash end address */
uint32_t tempSize = size; /* Temporary of size variation */
/* Calculating Flash end address */
endAddress = dest + tempSize;
/* Check for valid range of the target addresses */
if ((dest < pSSDConfig->PFlashBase) || (endAddress > (pSSDConfig->PFlashBase + pSSDConfig->PFlashSize)))
{
#if FEATURE_FLS_HAS_FLEX_NVM
if ((dest < pSSDConfig->DFlashBase) || (endAddress > (pSSDConfig->DFlashBase + pSSDConfig->DFlashSize)))
{
#endif
ret = STATUS_ERROR;
tempSize = 0U;
#if FEATURE_FLS_HAS_FLEX_NVM
}
#endif /* End of if FEATURE_FLS_HAS_FLEX_NVM */
}
*pSum = 0U;
/* Doing sum operation */
while (tempSize > 0U)
{
data = *(uint8_t *)(dest);
*pSum += data;
dest += 1U;
tempSize -= 1U;
++counter;
/* Check if need to serve callback function */
if (counter >= FLASH_CALLBACK_CS)
{
/* Serve callback function if counter reaches limitation */
if (NULL_CALLBACK != pSSDConfig->CallBack)
{
pSSDConfig->CallBack();
}
/* Reset counter */
counter = 0U;
}
}
return ret;
}
FLASH_DRV_ProgramSection
按照段来写入数据,但是写入的位置要先擦除。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_ProgramSection
* Description : Program the data found in the Section Program Buffer
* to previously erased locations in the Flash memory. Data is preloaded into
* the Section Program Buffer by writing to the acceleration Ram and FlexRam
* while it is set to function as a RAM. The Section Program Buffer is limited
* to the value of FlexRam divides by a ratio. Refer to the associate reference
* manual to get correct value of this ratio.
* For derivatives including swap feature, the swap indicator address is encountered
* during FlashProgramSection, it is bypassed without setting FPVIOL but the content
* are not be programmed. In addition, the content of source data used to program to
* swap indicator will be re-initialized to 0xFF after completion of this command.
*
* Implements : FLASH_DRV_ProgramSection_Activity
*END**************************************************************************/
status_t FLASH_DRV_ProgramSection(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
uint16_t number)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t temp;
/* Check RAMRDY bit of the flash configuration register */
if (0U == (FTFx_FCNFG & FTFx_FCNFG_RAMRDY_MASK))
{
/* Return an error code */
ret = STATUS_UNSUPPORTED;
}
else
{
#if FEATURE_FLS_HAS_FLEX_NVM
temp = pSSDConfig->DFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_DF_SECTION_CMD_ADDRESS_ALIGMENT) == 0U);
dest += 0x800000U - temp;
}
else
#endif
{
temp = pSSDConfig->PFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_PF_SECTION_CMD_ADDRESS_ALIGMENT) == 0U);
dest -= temp;
}
else
{
ret = STATUS_ERROR;
}
}
if (ret == STATUS_SUCCESS)
{
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register.
* Write 1 to clear
*/
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to command */
FTFx_FCCOB0 = FTFx_PROGRAM_SECTION;
FTFx_FCCOB1 = GET_BIT_16_23(dest);
FTFx_FCCOB2 = GET_BIT_8_15(dest);
FTFx_FCCOB3 = GET_BIT_0_7(dest);
FTFx_FCCOB4 = GET_BIT_8_15(number);
FTFx_FCCOB5 = GET_BIT_0_7(number);
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
}
}
return ret;
}
FLASH_DRV_EraseBlock
按照块来擦除,一块512KB。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_EraseBlock
* Description : Erases all addresses in an individual P-Flash or D-Flash block.
* For the derivatives including multiply logical P-Flash or D-Flash blocks,
* this API erases a single block in a single call.
*
* Implements : FLASH_DRV_EraseBlock_Activity
*END**************************************************************************/
status_t FLASH_DRV_EraseBlock(const flash_ssd_config_t * pSSDConfig,
uint32_t dest)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t temp; /* Temporary variable */
/* Check if the destination is aligned or not */
#if FEATURE_FLS_HAS_FLEX_NVM
temp = pSSDConfig->DFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_DF_BLOCK_CMD_ADDRESS_ALIGMENT) == 0U);
dest += 0x800000U - temp;
}
else
#endif
{
temp = pSSDConfig->PFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_PF_BLOCK_CMD_ADDRESS_ALIGMENT) == 0U);
dest -= temp;
}
else
{
ret = STATUS_ERROR;
}
}
if (STATUS_SUCCESS == ret)
{
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_ERASE_BLOCK;
FTFx_FCCOB1 = GET_BIT_16_23(dest);
FTFx_FCCOB2 = GET_BIT_8_15(dest);
FTFx_FCCOB3 = GET_BIT_0_7(dest);
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
}
return ret;
}
使用方法
FLASH_DRV_EraseBlock(&flashSSDConfig,0x00080000);
flashSSDConfig是初始化时候接收配置的结构体
每块大小 512K = 512 * 1024byte = 0x0008 0000
擦的时候要对齐,512K一块,不能随便哪个地方就起刷。
FLASH_DRV_VerifyBlock
校验块
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_VerifyBlock
* Description : Checks to see if an entire P-Flash or D-Flash block has been
* erased to the specified margin level. For the derivatives including multiply
* logical P-Flash or D-Flash blocks, this API erases a single block in a single call.
*
* Implements : FLASH_DRV_VerifyBlock_Activity
*END**************************************************************************/
status_t FLASH_DRV_VerifyBlock(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
uint8_t marginLevel)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t temp;
/* Check if the destination is aligned or not */
#if FEATURE_FLS_HAS_FLEX_NVM
temp = pSSDConfig->DFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->DFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_DF_BLOCK_CMD_ADDRESS_ALIGMENT) == 0U);
dest += 0x800000U - temp;
}
else
#endif
{
temp = pSSDConfig->PFlashBase;
if ((dest >= temp) && (dest < (temp + pSSDConfig->PFlashSize)))
{
DEV_ASSERT((dest % FEATURE_FLS_PF_BLOCK_CMD_ADDRESS_ALIGMENT) == 0U);
dest -= temp;
}
else
{
ret = STATUS_ERROR;
}
}
if (STATUS_SUCCESS == ret)
{
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_VERIFY_BLOCK;
FTFx_FCCOB1 = GET_BIT_16_23(dest);
FTFx_FCCOB2 = GET_BIT_8_15(dest);
FTFx_FCCOB3 = GET_BIT_0_7(dest);
FTFx_FCCOB4 = marginLevel;
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
}
return ret;
}
FLASH_DRV_GetEERAMProtection
从FlexRAM中检索EEPROM各部分的保护状态
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_GetEERAMProtection
* Description : Retrieves which EEPROM sections of FlexRAM are protected
* against program and erase operations. Considering the time consumption
* for getting protection is very low and even can be ignored, it is not necessary
* to utilize the Callback function to support the time-critical events
*
* Implements : FLASH_DRV_GetEERAMProtection_Activity
*END**************************************************************************/
status_t FLASH_DRV_GetEERAMProtection(uint8_t * protectStatus)
{
DEV_ASSERT(protectStatus != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
/* Check if EERAM is set for EEPROM */
if ((FTFx_FCNFG & FTFx_FCNFG_EEERDY_MASK) == FTFx_FCNFG_EEERDY_MASK)
{
*protectStatus = FTFx_FEPROT;
}
else
{
ret = STATUS_UNSUPPORTED;
}
return ret;
}
FLASH_DRV_SetEERAMProtection
从FlexRAM中设置EEPROM各部分的保护状态
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_SetEERAMProtection
* Description : Sets protection to the intended protection status for EEPROM us
* area of FlexRam. This is subject to a protection transition restriction.
* If there is a setting violation, it returns failed information and
* the current protection status will not be changed.
*
* Implements : FLASH_DRV_SetEERAMProtection_Activity
*END**************************************************************************/
status_t FLASH_DRV_SetEERAMProtection(uint8_t protectStatus)
{
status_t ret = STATUS_SUCCESS; /* Return code variable */
/* Check if FlexRAM is set for EEPROM */
if (0U == (FTFx_FCNFG & FTFx_FCNFG_EEERDY_MASK))
{
/* FlexRAM is not set for EEPROM */
ret = STATUS_UNSUPPORTED;
}
else
{
FTFx_FEPROT = protectStatus;
if (protectStatus != FTFx_FEPROT)
{
ret = STATUS_ERROR;
}
else
{
/* Do nothing */
}
}
return ret;
}
FLASH_DRV_SetFlexRamFunction
设置RAM功能,以什么功能模拟E方
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_SetFlexRamFunction
* Description : This function is used to change the function of the FlexRAM. When not partitioned for
* emulated EEPROM, the FlexRAM is typically used as traditional RAM.
* Otherwise, the FlexRam is typically used to store EEPROM data, the writing to EEPROM is normal write or
* quick write.
* In addition, this function may be used to get EEPROM status or complete interrupted EEPROM quick write process.
* For example, after partitioning to have EEPROM backup, FlexRAM is used for EEPROM
* use accordingly and if want to change FlexRAM to traditional RAM for FlashProgramSection() use, call this API
* with the function control code is 0xFFU.
*
* Implements : FLASH_DRV_SetFlexRamFunction_Activity
*END**************************************************************************/
status_t FLASH_DRV_SetFlexRamFunction(const flash_ssd_config_t * pSSDConfig,
flash_flexRam_function_control_code_t flexRamFuncCode,
uint16_t byteOfQuickWrite,
flash_eeprom_status_t * const pEEPROMStatus)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret; /* Return code variable */
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_SET_EERAM;
FTFx_FCCOB1 = (uint8_t)flexRamFuncCode;
if (flexRamFuncCode == EEE_QUICK_WRITE)
{
FTFx_FCCOB4 = (uint8_t)(byteOfQuickWrite >> 0x8U);
FTFx_FCCOB5 = (uint8_t)(byteOfQuickWrite & 0xFFU);
}
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
if ((flexRamFuncCode == EEE_STATUS_QUERY) && (ret == STATUS_SUCCESS))
{
if (pEEPROMStatus == NULL)
{
ret = STATUS_ERROR;
}
else
{
pEEPROMStatus->brownOutCode = FTFx_FCCOB5;
pEEPROMStatus->sectorEraseCount = (uint16_t)((uint16_t)FTFx_FCCOB8 << 8U);
pEEPROMStatus->sectorEraseCount |= (uint16_t)FTFx_FCCOB9;
pEEPROMStatus->numOfRecordReqMaintain = (uint16_t)((uint16_t)FTFx_FCCOB6 << 8U);
pEEPROMStatus->numOfRecordReqMaintain |= (uint16_t)FTFx_FCCOB7;
}
}
}
return ret;
}
FLASH_DRV_WaitEEWriteToFinish
等待模拟E方写入完成
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_WaitEEWriteToFinish
* Description : Write to EEPROM with data was aligned and wait until operation finish.
*
*END**************************************************************************/
static status_t FLASH_DRV_WaitEEWriteToFinish(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
const uint8_t * pData,
uint8_t step)
{
DEV_ASSERT(pData != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint32_t temp; /* Temporary variable */
if (0x01U == step)
{
*(uint8_t *)dest = *pData;
}
if (0x02U == step)
{
temp = (uint32_t)(pData[1]) << 8U;
temp |= (uint32_t)(pData[0]);
*(volatile uint16_t *)dest = (uint16_t)temp;
}
if (0x04U == step)
{
temp = (uint32_t)(pData[3]) << 24U;
temp |= (uint32_t)(pData[2]) << 16U;
temp |= (uint32_t)(pData[1]) << 8U;
temp |= (uint32_t)(pData[0]);
*(volatile uint32_t *)dest = temp;
}
while (0U == (FTFx_FCNFG & FTFx_FCNFG_EEERDY_MASK))
{
/* Wait till EEERDY bit is set
* Serve callback function as often as possible
*/
if (NULL_CALLBACK != pSSDConfig->CallBack)
{
(pSSDConfig->CallBack)();
}
}
/* Check for protection violation error */
if ((FTFx_FSTAT & (FTFx_FSTAT_MGSTAT0_MASK | FTFx_FSTAT_FPVIOL_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_RDCOLERR_MASK)) != 0U)
{
ret = STATUS_ERROR;
}
return ret;
}
FLASH_DRV_EEEWrite
写入模拟E方,它也可以用来写入数据到Flash,有些方案就是用这个接口来写入数据的。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_EEEWrite
* Description : Write data to FlexRAM section which is partitioned
* as EEPROM use for EEPROM operation. After data has been written to EEPROM
* use section of FlexRAM, the EEPROM file system will create new data record
* in EEPROM back-up area of FlexNVM in round-robin fashion.
* There is no alignment constraint for destination and size parameters
* provided by user. However, according to user's input provided, this
* API will set priority to write to FlexRAM with following rules:
* 32-bit writing is invoked if destination is 32 bit aligned and size
* is not less than 32 bits.
* 16-bit writing is invoked if destination is 16 bit aligned and size
* is not less than 16 bits.
* 8-bit writing is invoked if destination is 8 bit aligned and size
* is not less than 8 bits.
* When EEPROM was set to EEPROM quick writes mode, the dest address
* should be aligned 4 bytes,the size should be divided by 4.
* Implements : FLASH_DRV_EEEWrite_Activity
*END**************************************************************************/
status_t FLASH_DRV_EEEWrite(const flash_ssd_config_t * pSSDConfig,
uint32_t dest,
uint32_t size,
const uint8_t * pData)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(pData != NULL);
DEV_ASSERT(size > 0U);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint8_t i;
/* Check if EEE is enabled */
if ((FTFx_FCNFG & FTFx_FCNFG_EEERDY_MASK) == FTFx_FCNFG_EEERDY_MASK)
{
/* Check range */
if ((dest < pSSDConfig->EERAMBase) || ((dest + size) > (pSSDConfig->EERAMBase + pSSDConfig->EEESize)))
{
ret = STATUS_ERROR;
}
while ((size > 0U) && (ret == STATUS_SUCCESS))
{
/* Dest is 32bit-aligned and size is not less than 4 */
if ((0U == (dest & 3U)) && (size >= 4U))
{
i = 4U;
}
else if ((0U == (dest & 1U)) && (size >= 2U))
{
i = 2U;
}
else
{
i = 1U;
}
ret = FLASH_DRV_WaitEEWriteToFinish(pSSDConfig,
dest,
pData,
i);
/* Update destination address for next iteration */
dest += i;
/* Update size for next iteration */
size -= i;
/* Update data for next iteration */
pData += i;
}
}
else
{
ret = STATUS_UNSUPPORTED;
}
return ret;
}
FLASH_DRV_DEFlashPartition
准备FlexNVM块用于D-Flash、EEPROM备份或组合并初始化FlexRAM,模拟E方功能初始化的时候要用。
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_DEFlashPartition
* Description : Prepares the FlexNVM block for use as D-Flash, EEPROM backup, or a combination
* of both and initializes the FlexRAM.
* The single partition choice should be used through entire life time of a given
* application to guarantee the Flash endurance and data retention of Flash module.
*
* Implements : FLASH_DRV_DEFlashPartition_Activity
*END**************************************************************************/
status_t FLASH_DRV_DEFlashPartition(const flash_ssd_config_t * pSSDConfig,
uint8_t uEEEDataSizeCode,
uint8_t uDEPartitionCode,
uint8_t uCSEcKeySize,
bool uSFE,
bool flexRamEnableLoadEEEData)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(uCSEcKeySize <= CSE_KEY_SIZE_CODE_MAX);
status_t ret; /* Return code variable */
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL & MGSTAT0 flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_PROGRAM_PARTITION;
FTFx_FCCOB1 = uCSEcKeySize;
FTFx_FCCOB2 = (uint8_t)(uSFE ? 1U : 0U);
FTFx_FCCOB3 = (uint8_t)(flexRamEnableLoadEEEData ? 0U : 1U);
FTFx_FCCOB4 = uEEEDataSizeCode;
FTFx_FCCOB5 = uDEPartitionCode;
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
return ret;
}
FLASH_DRV_GetDFlashProtection
获取Dflash保护
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_GetDFlashProtection
* Description : Retrieves current P-Flash protection status. Considering the time consumption
* for getting protection is very low and even can be ignored, it is not necessary to utilize
* the Callback function to support the time-critical events.
*
* Implements : FLASH_DRV_GetDFlashProtection_Activity
*END**************************************************************************/
status_t FLASH_DRV_GetDFlashProtection(const flash_ssd_config_t * pSSDConfig,
uint8_t * protectStatus)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(protectStatus != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
/* Check if size of DFlash = 0 */
if (pSSDConfig->DFlashSize == 0U)
{
ret = STATUS_UNSUPPORTED;
}
else
{
*protectStatus = FTFx_FDPROT;
}
return ret;
}
FLASH_DRV_SetDFlashProtection
设置DFlash保护
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_SetDFlashProtection
* Description : Sets the D-Flash protection to the intended protection status.
* Setting D-Flash protection status is subject to a protection transition restriction.
* If there is a setting violation, it returns failed information
* and the current protection status will not be changed.
*
* Implements : FLASH_DRV_SetDFlashProtection_Activity
*END**************************************************************************/
status_t FLASH_DRV_SetDFlashProtection(const flash_ssd_config_t * pSSDConfig,
uint8_t protectStatus)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
/* Check if size of DFlash = 0 */
if (pSSDConfig->DFlashSize == 0U)
{
ret = STATUS_UNSUPPORTED;
}
else
{
FTFx_FDPROT = protectStatus;
if (protectStatus != FTFx_FDPROT)
{
ret = STATUS_ERROR;
}
else
{
/* Do nothing */
}
}
return ret;
}
FLASH_DRV_PFlashSwap
用外面的数据交换Pflash里面的数据
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_PFlashSwap
* Description : Provides to user with an ability to interfere in a swap progress by letting the
* user code know about the swap state in each phase of the process. This is done via pSwapCallBack()
* parameter. To stop at each intermediate swap state, set the return value of
* this callback function to FALSE. To complete swap process within a single call,
* set the return value of this function to TRUE.
*
* Erase the non-active swap indicator somewhere in the application code
* or in the swap call back function when swap system is in UPDATE state.
*
* In addition, if user does not want to use the swap call back parameter, pass the NULL_SWAP_CALLBACK
* as a null pointer. In this situation, the PFlashSwap() behaves in the same way as setting the return
* value of pSwapCallBack to TRUE and the user does not need to erase the non-active swap
* indicator when the swap system is in UPDATE state.
* The swap indicator provided by the user must be within the lower half of P-Flash block but not in the
* Flash configuration area. If P-Flash block has two logical blocks, the swap indicator must be
* in P-Flash block 0. If the P-Flash block has four logical blocks, the swap indicator can be in block
* 0 or block 1. It must not be in the Flash configuration field.
* The user must use the same swap indicator for all swap control code except report swap status once
* swap system has been initialized. To refresh swap system to un-initialization state,
* use the FlashEraseAllBlock() to clean up the swap environment.
*
*END**************************************************************************/
status_t FLASH_DRV_PFlashSwap(const flash_ssd_config_t * pSSDConfig,
uint32_t addr,
flash_swap_callback_t pSwapCallback)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(pSwapCallback != NULL);
status_t ret = STATUS_SUCCESS; /* Return code variable */
uint8_t currentSwapMode, currentSwapBlockStatus, nextSwapBlockStatus;
bool swapContinue;
currentSwapMode = 0xFFU;
currentSwapBlockStatus = 0xFFU;
nextSwapBlockStatus = 0xFFU;
swapContinue = false;
/* Report current swap state */
ret = FLASH_DRV_PFlashSwapCtl(pSSDConfig, addr, FTFx_SWAP_REPORT_STATUS, ¤tSwapMode, ¤tSwapBlockStatus, &nextSwapBlockStatus);
if (STATUS_SUCCESS == ret)
{
if ((FTFx_SWAP_UNINIT == currentSwapMode) || (FTFx_SWAP_READY == currentSwapMode) || (FTFx_SWAP_UPDATE == currentSwapMode))
{
/* If current swap mode is Uninitialized */
if (FTFx_SWAP_UNINIT == currentSwapMode)
{
/* Initialize Swap to Initialized/READY state */
ret = FLASH_DRV_PFlashSwapCtl(pSSDConfig,
addr,
FTFx_SWAP_SET_INDICATOR_ADDR,
¤tSwapMode,
¤tSwapBlockStatus,
&nextSwapBlockStatus);
}
/* If current swap mode is Initialized/Ready */
else if (FTFx_SWAP_READY == currentSwapMode)
{
/* Initialize Swap to UPDATE state */
ret = FLASH_DRV_PFlashSwapCtl(pSSDConfig,
addr,
FTFx_SWAP_SET_IN_PREPARE,
¤tSwapMode,
¤tSwapBlockStatus,
&nextSwapBlockStatus);
}
else
{
/* If (FTFx_SWAP_UPDATE == currentSwapMode) do nothing */
}
/* Check for the success of command execution
* Report the current swap state to user via callback
*/
if ((NULL_SWAP_CALLBACK != pSwapCallback) && (STATUS_SUCCESS == ret))
{
swapContinue = pSwapCallback(currentSwapMode);
if (swapContinue == true)
{
/* Report current swap state */
ret = FLASH_DRV_PFlashSwapCtl(pSSDConfig,
addr,
FTFx_SWAP_REPORT_STATUS,
¤tSwapMode,
¤tSwapBlockStatus,
&nextSwapBlockStatus);
}
}
}
else
{
/* Do nothing */
}
if ((NULL_SWAP_CALLBACK == pSwapCallback) && (FTFx_SWAP_UPDATE == currentSwapMode))
{
/* Erase indicator sector in non active block to proceed swap system to update-erased state */
ret = FLASH_DRV_EraseSector(pSSDConfig, addr + (pSSDConfig->PFlashSize >> 1U), (uint32_t)FEATURE_FLS_PF_BLOCK_SECTOR_SIZE);
if (STATUS_SUCCESS == ret)
{
/* Now the swap state must be Update-Erased, so report current swap state */
ret = FLASH_DRV_PFlashSwapCtl(pSSDConfig,
addr,
FTFx_SWAP_REPORT_STATUS,
¤tSwapMode,
¤tSwapBlockStatus,
&nextSwapBlockStatus);
}
}
/* If current swap mode is Update or Update-Erased */
if (FTFx_SWAP_UPDATE_ERASED == currentSwapMode)
{
if (NULL_SWAP_CALLBACK == pSwapCallback)
{
swapContinue = true;
}
else
{
swapContinue = pSwapCallback(currentSwapMode);
}
if (swapContinue == true)
{
/* Progress Swap to COMPLETE State */
ret = FLASH_DRV_PFlashSwapCtl(pSSDConfig,
addr,
FTFx_SWAP_SET_IN_COMPLETE,
¤tSwapMode,
¤tSwapBlockStatus,
&nextSwapBlockStatus);
}
}
}
return ret;
}
FLASH_DRV_PFlashSwapCtl
交换数据时候的控制
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_PFlashSwapCtl
* Description : Performs swap control command corresponding with the swap
* control code provided via the swap command parameter.
*
*END**************************************************************************/
status_t FLASH_DRV_PFlashSwapCtl(const flash_ssd_config_t * pSSDConfig,
uint32_t addr,
uint8_t swapcmd,
uint8_t * pCurrentSwapMode,
uint8_t * pCurrentSwapBlockStatus,
uint8_t * pNextSwapBlockStatus)
{
DEV_ASSERT(pSSDConfig != NULL);
DEV_ASSERT(pCurrentSwapMode != NULL);
DEV_ASSERT(pCurrentSwapBlockStatus != NULL);
DEV_ASSERT(pNextSwapBlockStatus != NULL);
status_t ret; /* Return code variable */
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_PFLASH_SWAP;
FTFx_FCCOB1 = GET_BIT_16_23(addr);
FTFx_FCCOB2 = GET_BIT_8_15(addr);
FTFx_FCCOB3 = GET_BIT_0_7(addr);
FTFx_FCCOB4 = swapcmd;
FTFx_FCCOB5 = 0xFFU;
FTFx_FCCOB6 = 0xFFU;
FTFx_FCCOB7 = 0xFFU;
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
if (STATUS_SUCCESS == ret)
{
*pCurrentSwapMode = FTFx_FCCOB5;
*pCurrentSwapBlockStatus = FTFx_FCCOB6;
*pNextSwapBlockStatus = FTFx_FCCOB7;
}
}
return ret;
}
FLASH_DRV_EraseAllBlockUnsecure
没安全保护的时候擦除全部块
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_EraseAllBlockUnsecure
* Description : Erases all Flash memory, initializes the FlexRAM, verifies
* all memory contents, and then releases the MCU security.
*
* Implements : FLASH_DRV_EraseAllBlockUnsecure_Activity
*END**************************************************************************/
status_t FLASH_DRV_EraseAllBlockUnsecure(const flash_ssd_config_t * pSSDConfig)
{
DEV_ASSERT(pSSDConfig != NULL);
status_t ret; /* Return code variable */
/* Check CCIF to verify the previous command is completed */
if (0U == (FTFx_FSTAT & FTFx_FSTAT_CCIF_MASK))
{
ret = STATUS_BUSY;
}
else
{
/* Clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1 to clear */
CLEAR_FTFx_FSTAT_ERROR_BITS;
/* Passing parameter to the command */
FTFx_FCCOB0 = FTFx_ERASE_ALL_BLOCK_UNSECURE;
/* Calling flash command sequence function to execute the command */
ret = FLASH_DRV_CommandSequence(pSSDConfig);
}
return ret;
}
FLASH_DRV_EnableCmdCompleteInterupt
使能FTFC命令完成中断
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_EnableCmdCompleteInterupt
* Description : Enable the command complete interrupt is generated when
* an FTFC command completes.
*
* Implements : FLASH_DRV_EnableCmdCompleteInterupt_Activity
*END**************************************************************************/
status_t FLASH_DRV_EnableCmdCompleteInterupt(void)
{
const IRQn_Type flashIrqId = FTFC_COMMAND_COMPLETE_IRQS;
/* Enable the command complete interrupt */
FTFx_FCNFG |= FTFx_FCNFG_CCIE_MASK;
INT_SYS_EnableIRQ(flashIrqId);
return STATUS_SUCCESS;
}
FLASH_DRV_DisableCmdCompleteInterupt
失能FTFC命令完成中断
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_DisableCmdCompleteInterupt
* Description : Disable the command complete interrupt.
*
* Implements : FLASH_DRV_DisableCmdCompleteInterupt_Activity
*END**************************************************************************/
void FLASH_DRV_DisableCmdCompleteInterupt(void)
{
const IRQn_Type flashIrqId = FTFC_COMMAND_COMPLETE_IRQS;
/* Disable the command complete interrupt */
FTFx_FCNFG &= (uint8_t)(~FTFx_FCNFG_CCIE_MASK);
INT_SYS_DisableIRQ(flashIrqId);
}
FLASH_DRV_EnableReadColisionInterupt
使能读取错误的中断
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_EnableReadColisionInterupt
* Description : Enable the read collision error interrupt generation when an
* FTFC read collision error occurs.
*
* Implements : FLASH_DRV_EnableReadColisionInterupt_Activity
*END**************************************************************************/
status_t FLASH_DRV_EnableReadColisionInterupt(void)
{
const IRQn_Type flashIrqId = FTFC_READ_COLLISION_IRQS;
/* Enable the read collision error interrupt */
FTFx_FCNFG |= FTFx_FCNFG_RDCOLLIE_MASK;
INT_SYS_EnableIRQ(flashIrqId);
return STATUS_SUCCESS;
}
FLASH_DRV_DisableReadColisionInterupt
失能读取错误的中断
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_DisableReadColisionInterupt
* Description : Disable the read collision error interrupt
*
* Implements : FLASH_DRV_DisableReadColisionInterupt_Activity
*END**************************************************************************/
void FLASH_DRV_DisableReadColisionInterupt(void)
{
const IRQn_Type flashIrqId = FTFC_READ_COLLISION_IRQS;
/* Disable the read collision error interrupt */
FTFx_FCNFG &= (uint8_t)(~FTFx_FCNFG_RDCOLLIE_MASK);
INT_SYS_DisableIRQ(flashIrqId);
}
FLASH_DRV_GetDefaultConfig
获取默认Flash配置
/*FUNCTION**********************************************************************
*
* Function Name : FLASH_DRV_GetDefaultConfig
* Description : This function will get default flash user configuration.
*
* Implements : FLASH_DRV_GetDefaultConfig_Activity
*END**************************************************************************/
void FLASH_DRV_GetDefaultConfig(flash_user_config_t * const config)
{
DEV_ASSERT(config != NULL);
config->PFlashBase = 0x00000000U;
config->PFlashSize = FEATURE_FLS_PF_BLOCK_SIZE;
config->DFlashBase = 0x10000000U;
config->EERAMBase = 0x14000000U;
config->CallBack = NULL_CALLBACK;
}
操作注意事项
1、flash地址必须按要求对齐。
2、flash操作前要关闭全局中断,操作后再开启。
3、flash操作时间较长,如果启动了看门狗,必须倍频看门狗频率延长复位时间,防止在操作flash时复位;或者FTFC的Callback回调函数,以便在Flash驱动API调用过程中喂狗,防止复位。
4、flash操作时不要操作正在运行这一块。
5、操作之前必须将系统频率切换为正常频率。