1951 lines
80 KiB
C
1951 lines
80 KiB
C
/**
|
|
* @file module_driver_flash.c
|
|
* @author Flagchip
|
|
* @brief Flash driver source code
|
|
* @version 2.0.0
|
|
* @date 2024-08-20
|
|
*
|
|
* SDK Version: 2.6.0
|
|
*
|
|
|
|
* @copyright Copyright (c) 2020-2024 Flagchip Semiconductors Co., Ltd.
|
|
*/
|
|
/* ********************************************************************************
|
|
* Revision History:
|
|
*
|
|
* Version Date Initials CR# Descriptions
|
|
* --------- ---------- ------------ ---------- ---------------
|
|
* 0.1.0 29/12/2022 GuangLong N/A First version for FC7300
|
|
* 0.2.0 13/02/2022 GuangLong N/A remove the nvr function
|
|
* 2.0.0 30/07/2024 HowardWang N/A Vesion 2.0
|
|
* 2.1.0 30/11/2024 HowardWang N/A Add support for FC7300F8MDQ
|
|
* 2.3.5 10/06/2025 HowardWang N/A Add flash DMA abort, update flash DMA error process.
|
|
******************************************************************************** */
|
|
|
|
#include "module_driver_flash.h"
|
|
|
|
#if FLASH_INSTANCE_COUNT > 0U
|
|
|
|
#ifndef FLASH_DEV_ERROR_REPORT
|
|
#define FLASH_DEV_ERROR_REPORT STD_OFF
|
|
#endif
|
|
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
#define FLASH_ReportDevError(func, error) ReportDevError(FLASH_MODULE_ID, func, error)
|
|
#endif
|
|
|
|
/* ################################################################################## */
|
|
/* ####################################### Macro #################################### */
|
|
|
|
/** flash driver header for finding function in special address */
|
|
|
|
static FLASH_ROM_API_ENTRY_T *const s_pFlashDriver[FLASH_INSTANCE_COUNT] = FLASHDRV_BASE_ADDR;
|
|
|
|
|
|
/* ################################################################################## */
|
|
/* ################################ Local Variables ################################# */
|
|
|
|
|
|
/* ################################################################################## */
|
|
/* ########################### Local Prototype Functions ############################ */
|
|
static FLASH_StatusType FLASHDRIVER_EraseCheck(FLASH_DRIVER_ParamType *pFlashParam);
|
|
static FLASH_StatusType FLASHDRIVER_WriteCheck(FLASH_DRIVER_ParamType *pFlashParam);
|
|
static FLASH_StatusType NVRDRIVER_EraseCheck(FLASH_DRIVER_ParamType *pFlashParam);
|
|
static FLASH_StatusType NVRDRIVER_WriteCheck(FLASH_DRIVER_ParamType *pFlashParam);
|
|
static FLASH_StatusType FLASHDRIVER_GetFlashConfig(uint32_t u32Address, FLASH_API_ERASESECTOR_TYPE *pFlash_api_cfg);
|
|
static void FLASHDRIVER_INTSingleErase(FLASH_HandleType *pFlashHandle);
|
|
static void FLASHDRIVER_INTSingleProgram(FLASH_HandleType *pFlashHandle);
|
|
static ECC_StatusType FLASHDRIVER_EccCheck(FLASH_HandleType *pFlashHandle);
|
|
static uint8_t FLASHDRIVER_MsrIsOn(void);
|
|
|
|
|
|
/* ################################################################################## */
|
|
/* ########################### Global Prototype Functions ########################### */
|
|
|
|
|
|
|
|
|
|
/* ################################################################################## */
|
|
/* ################################ Local Functions ################################# */
|
|
|
|
/**
|
|
* @brief Flash Driver Function for Erasing Address Check
|
|
*
|
|
* @param pFlashParam flash driver erase parameter
|
|
*/
|
|
static FLASH_StatusType FLASHDRIVER_EraseCheck(FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
uint32_t u32Addr, u32Length;
|
|
FLASH_StatusType tRetVal;
|
|
|
|
u32Addr = pFlashParam->u32Address;
|
|
u32Length = pFlashParam->u32Length;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
pFlashParam->u32ErrorAddress = 0x0U;
|
|
|
|
if ((u32Addr >= PFLASH_ADDR_START) && ((u32Addr + u32Length) <= (PFLASH_ADDR_END + 1)))
|
|
{
|
|
/* check address align */
|
|
if (u32Addr & (PFLASH_ERASE_SECTOR_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
else
|
|
{
|
|
/* check length align */
|
|
if (u32Length & (PFLASH_ERASE_SECTOR_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_SIZE;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
}
|
|
}
|
|
else if ((DFLASH_ADDR_START <= u32Addr) && ((u32Addr + u32Length) <= (DFLASH_ADDR_END + 1)))
|
|
{
|
|
/* check address align */
|
|
if (u32Addr & (DFLASH_ERASE_SECTOR_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
else
|
|
{
|
|
/* check length align */
|
|
if (u32Length & (DFLASH_ERASE_SECTOR_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_SIZE;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_PARAM;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief Flash Driver Function for Writing address Check
|
|
*
|
|
* @param pFlashParam flash driver write parameter
|
|
*/
|
|
static FLASH_StatusType FLASHDRIVER_WriteCheck(FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
uint32_t u32Addr, u32Length;
|
|
FLASH_StatusType tRetVal;
|
|
u32Addr = pFlashParam->u32Address;
|
|
u32Length = pFlashParam->u32Length;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
pFlashParam->u32ErrorAddress = 0x0U;
|
|
|
|
if ((u32Addr >= PFLASH_ADDR_START) && ((u32Addr + u32Length) <= (PFLASH_ADDR_END + 1)))
|
|
{
|
|
/* check address align */
|
|
if (u32Addr & (PFLASH_PROGRAM_PAGE_MIN_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
pFlashParam->u32ErrorAddress = pFlashParam->u32Address;
|
|
}
|
|
/* check length align */
|
|
else
|
|
{
|
|
if (u32Length & (PFLASH_PROGRAM_PAGE_MIN_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_SIZE;
|
|
pFlashParam->u32ErrorAddress = pFlashParam->u32Address;
|
|
}
|
|
}
|
|
}
|
|
else if ((DFLASH_ADDR_START <= u32Addr) && ((u32Addr + u32Length) <= (DFLASH_ADDR_END + 1)))
|
|
{
|
|
/* check length align */
|
|
if (u32Addr & (DFLASH_PROGRAM_PAGE_MIN_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
pFlashParam->u32ErrorAddress = pFlashParam->u32Address;
|
|
}
|
|
else
|
|
{
|
|
if (u32Length & (DFLASH_PROGRAM_PAGE_MIN_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_SIZE;
|
|
pFlashParam->u32ErrorAddress = pFlashParam->u32Address;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_PARAM;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief Flash Driver Function for Erasing NVR Address Check
|
|
*
|
|
* @param pFlashParam flash driver erase NVR parameter
|
|
*/
|
|
static FLASH_StatusType NVRDRIVER_EraseCheck(FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
uint32_t u32Addr, u32Length;
|
|
FLASH_StatusType tRetVal;
|
|
u32Addr = pFlashParam->u32Address;
|
|
u32Length = pFlashParam->u32Length;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
|
|
#if(FLASH_FC7240F2MDS == STD_ON)
|
|
if ((NVR0_FLASH_ADDR_START <= u32Addr && (u32Addr + u32Length) <= (NVR0_FLASH_ADDR_END + 1)) \
|
|
|| (NVR1_FLASH_ADDR_START <= u32Addr && (u32Addr + u32Length) <= (NVR1_FLASH_ADDR_END + 1)) \
|
|
|| (NVR2_FLASH_ADDR_START <= u32Addr && (u32Addr + u32Length) <= (NVR2_FLASH_ADDR_END + 1))
|
|
)
|
|
#elif((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
if ((NVR0_FLASH_ADDR_START <= u32Addr && (u32Addr + u32Length) <= (NVR0_FLASH_ADDR_END + 1)) \
|
|
|| (NVR2_FLASH_ADDR_START <= u32Addr && (u32Addr + u32Length) <= (NVR2_FLASH_ADDR_END + 1))
|
|
)
|
|
#elif((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7300F8MDQ == STD_ON))
|
|
if (NVR_FLASH_ADDR_START <= u32Addr && (u32Addr + u32Length) <= (NVR_FLASH_ADDR_END + 1))
|
|
#endif
|
|
{
|
|
/* check address align */
|
|
if (u32Addr & (NVR_ERASE_SECTOR_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
else
|
|
{
|
|
/* check length align */
|
|
if (u32Length & (NVR_ERASE_SECTOR_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_SIZE;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_PARAM;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief Flash Driver Function for Writing NVR address Check
|
|
*
|
|
* @param pFlashParam flash driver write NVR parameter
|
|
*/
|
|
static FLASH_StatusType NVRDRIVER_WriteCheck(FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
uint32_t u32Addr, u32Length;
|
|
FLASH_StatusType tRetVal;
|
|
|
|
u32Addr = pFlashParam->u32Address;
|
|
u32Length = pFlashParam->u32Length;
|
|
|
|
tRetVal = FLASH_ERROR_OK;
|
|
pFlashParam->u32ErrorAddress = 0x0U;
|
|
|
|
#if(FLASH_FC7240F2MDS == STD_ON)
|
|
if ((NVR0_FLASH_ADDR_START <= u32Addr && u32Addr + u32Length <= NVR0_FLASH_ADDR_END + 1) || \
|
|
(NVR1_FLASH_ADDR_START <= u32Addr && u32Addr + u32Length <= NVR1_FLASH_ADDR_END + 1) || \
|
|
(NVR2_FLASH_ADDR_START <= u32Addr && u32Addr + u32Length <= NVR2_FLASH_ADDR_END + 1))
|
|
#elif((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
if ((NVR0_FLASH_ADDR_START <= u32Addr && (u32Addr + u32Length) <= (NVR0_FLASH_ADDR_END + 1)) \
|
|
|| (NVR2_FLASH_ADDR_START <= u32Addr && (u32Addr + u32Length) <= (NVR2_FLASH_ADDR_END + 1))
|
|
)
|
|
#elif((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7300F8MDQ == STD_ON))
|
|
if (NVR_FLASH_ADDR_START <= u32Addr && (u32Addr + u32Length) <= (NVR_FLASH_ADDR_END + 1))
|
|
#endif
|
|
{
|
|
/* check address align */
|
|
if (u32Addr & (NVR_PROGRAM_PAGE_MIN_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
pFlashParam->u32ErrorAddress = pFlashParam->u32Address;
|
|
}
|
|
/* check length align */
|
|
else
|
|
{
|
|
if (u32Length & (NVR_PROGRAM_PAGE_MIN_SIZE - 1U))
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_SIZE;
|
|
pFlashParam->u32ErrorAddress = pFlashParam->u32Address;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_PARAM;
|
|
pFlashParam->u32ErrorAddress = u32Addr;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief Get Flash Configuration
|
|
*
|
|
* @param u32Address the flash address
|
|
* @param pFlash_api_cfg out flash parameter
|
|
*/
|
|
static FLASH_StatusType FLASHDRIVER_GetFlashConfig(uint32_t u32Address, FLASH_API_ERASESECTOR_TYPE *pFlash_api_cfg)
|
|
{
|
|
FLASH_StatusType tRetVal;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
uint32 u32Index = 0;
|
|
|
|
if ((u32Address >= PFLASH_ADDR_START) && (u32Address < PFLASH_ADDR_START + PFLASH_SIZE))
|
|
{
|
|
/* PFLASH bank index */
|
|
u32Index = (u32Address - PFLASH_ADDR_START) / PFLASH_BANK_SIZE;
|
|
pFlash_api_cfg->blk_sel = FLASH_BLOCK_SELECT0 + u32Index;
|
|
pFlash_api_cfg->dest = u32Address;
|
|
}
|
|
else if ((u32Address >= DFLASH_ADDR_START) && (u32Address <= DFLASH_ADDR_END))
|
|
{
|
|
/* DFLASH bank index */
|
|
u32Index = (u32Address - DFLASH_ADDR_START) / DFLASH_BANK_SIZE;
|
|
pFlash_api_cfg->blk_sel = FLASH_DATA_BLOCK_SELECT0 + u32Index;
|
|
pFlash_api_cfg->dest = u32Address;
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief flash driver single erase
|
|
* @param[in] Flash instance
|
|
* @return none
|
|
*/
|
|
static void FLASHDRIVER_INTSingleErase(FLASH_HandleType *pFlashHandle)
|
|
{
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
FLASH_API_ERASESECTOR_TYPE tFlash_api_cfg = {0};
|
|
uint8_t u8IsEnInterupt;
|
|
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_ENABLE_HOLD_CFG(1);
|
|
if(NULL != pFlashHandle->tSettings.pUnlockCallback)
|
|
{
|
|
pFlashHandle->tSettings.pUnlockCallback(pFlashHandle->tStatus.u32CurrentAddress);
|
|
}
|
|
FLASHDRIVER_GetFlashConfig(pFlashHandle->tStatus.u32CurrentAddress, &tFlash_api_cfg);
|
|
|
|
pFlashHandle->tStatus.u32CurrentAddress += pFlashHandle->tStatus.u32EraseSectorSize;
|
|
/* Disable Inetrrupt*/
|
|
u8IsEnInterupt = FLASHDRIVER_MsrIsOn();//0 disable ,1 enable
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsid i");
|
|
}
|
|
|
|
if (FLASH_HARDWARE_STATUS_IDLE == (((*(volatile uint32 *)FLASH_HARDWARE_STATUS_ADDR) & FLASH_HARDWARE_STATUS_MASK) >> 16))
|
|
{
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON))
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector(&tFlash_api_cfg, FLASH_API_ENABLE, FLASH_API_SIZE);
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
tFlash_api_cfg.int_en = FLASH_API_ENABLE;
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector(&tFlash_api_cfg);
|
|
#endif
|
|
}
|
|
/* Recover Inetrrupt*/
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsie i");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief flash driver single program
|
|
* @param[in] Flash instance
|
|
* @return none
|
|
*/
|
|
static void FLASHDRIVER_INTSingleProgram(FLASH_HandleType *pFlashHandle)
|
|
{
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
FLASH_API_PRGM_CFG_TYPE tFlash_api_cfg = {0};
|
|
uint32_t u32ProgramEndAddr, u32EndAddr;
|
|
uint8_t u8IsEnInterupt;
|
|
|
|
u32EndAddr = pFlashHandle->tStatus.u32Address + pFlashHandle->tStatus.u32Length;
|
|
u32ProgramEndAddr = ((pFlashHandle->tStatus.u32CurrentAddress + FLASH_PROGRAM_PAGE_MAX_SIZE) & ~(FLASH_PROGRAM_PAGE_MAX_SIZE - 1U));
|
|
u32ProgramEndAddr = ((u32ProgramEndAddr > u32EndAddr) ? u32EndAddr : u32ProgramEndAddr);
|
|
pFlashHandle->tStatus.u32ProgramSize = u32ProgramEndAddr - pFlashHandle->tStatus.u32CurrentAddress;
|
|
if(NULL != pFlashHandle->tSettings.pUnlockCallback)
|
|
{
|
|
pFlashHandle->tSettings.pUnlockCallback(pFlashHandle->tStatus.u32CurrentAddress);
|
|
}
|
|
tFlash_api_cfg.dest = pFlashHandle->tStatus.u32CurrentAddress;
|
|
tFlash_api_cfg.size = (uint32_t)(pFlashHandle->tStatus.u32ProgramSize) >> 2; /* one data is 4 bytes */
|
|
tFlash_api_cfg.pData = (uint32_t *)(pFlashHandle->tStatus.pDate);
|
|
tFlash_api_cfg.wdg_tune = WDG_TUNE_DISABLE;
|
|
tFlash_api_cfg.pgff = FLASH_REG_BIT_CFG_DISABLE;
|
|
|
|
pFlashHandle->tStatus.u32CurrentAddress += pFlashHandle->tStatus.u32ProgramSize;
|
|
/* Disable Inetrrupt*/
|
|
u8IsEnInterupt = FLASHDRIVER_MsrIsOn();//0 disable ,1 enable
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsid i");
|
|
}
|
|
if (FLASH_HARDWARE_STATUS_IDLE == (((*(volatile uint32 *)FLASH_HARDWARE_STATUS_ADDR) & FLASH_HARDWARE_STATUS_MASK) >> 16))
|
|
{
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON))
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Program(&tFlash_api_cfg, FLASH_API_ENABLE, FLASH_API_SIZE);
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
tFlash_api_cfg.int_en = FLASH_API_ENABLE;
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Program(&tFlash_api_cfg);
|
|
#endif
|
|
}
|
|
/* Recover Inetrrupt*/
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsie i");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Flash driver single program
|
|
* @param[in] Flash instance
|
|
* @return Have ecc or not
|
|
*/
|
|
static ECC_StatusType FLASHDRIVER_EccCheck(FLASH_HandleType *pFlashHandle)
|
|
{
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
ECC_StatusType tRetVal;
|
|
volatile uint8_t u8RealData;
|
|
uint32 u32ReadAddr, u32ApiReturnValue;
|
|
uint32 u32EccCont = FMC0->FEEC;
|
|
/* Disable ECC */
|
|
FMC0->FEEC = 0x00000080u;
|
|
/** Clear ECC flag*/
|
|
#if(FLASH_FC7240F2MDS == STD_ON)
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_128(FLASH_ECC_CHECK_MASK);
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON))
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_128(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P1(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P1_128(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_ECC_CHECK_MASK);
|
|
#elif((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON))
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P1(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_ECC_CHECK_MASK);
|
|
#elif((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_128(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_ECC_CHECK_MASK);
|
|
#endif
|
|
/** Readback*/
|
|
for(u32ReadAddr = pFlashHandle->tStatus.u32Address; u32ReadAddr < pFlashHandle->tStatus.u32Address + pFlashHandle->tStatus.u32Length; u32ReadAddr++)
|
|
{
|
|
u8RealData = *(uint8_t *)u32ReadAddr;
|
|
}
|
|
/** Check ECC*/
|
|
#if(FLASH_FC7240F2MDS == STD_ON)
|
|
u32ApiReturnValue = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_ECC_CHECK_MASK);
|
|
u32ApiReturnValue |= (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_128(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_128(FLASH_ECC_CHECK_MASK);
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON))
|
|
u32ApiReturnValue = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_ECC_CHECK_MASK);
|
|
u32ApiReturnValue |= (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_128(FLASH_ECC_CHECK_MASK);
|
|
u32ApiReturnValue |= (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P1(FLASH_ECC_CHECK_MASK);
|
|
u32ApiReturnValue |= (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P1_128(FLASH_ECC_CHECK_MASK);
|
|
u32ApiReturnValue |= (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P2(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_128(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P1(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P1_128(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_ECC_CHECK_MASK);
|
|
#elif((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON))
|
|
u32ApiReturnValue = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_ECC_CHECK_MASK);
|
|
u32ApiReturnValue |= (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P1(FLASH_ECC_CHECK_MASK);
|
|
u32ApiReturnValue |= (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P2(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P1(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_ECC_CHECK_MASK);
|
|
#elif((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
u32ApiReturnValue = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_ECC_CHECK_MASK);
|
|
u32ApiReturnValue |= (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_128(FLASH_ECC_CHECK_MASK);
|
|
u32ApiReturnValue |= (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P2(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_128(FLASH_ECC_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_ECC_CHECK_MASK);
|
|
#endif
|
|
/* Recover ECC control register*/
|
|
FMC0->FEEC = u32EccCont;
|
|
if(u32ApiReturnValue == STATUS_SUCCESS)
|
|
{
|
|
tRetVal = FLASH_ECC_ERROR_NONE;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITING_ECC;
|
|
tRetVal = FLASH_ECC_ERROR_DBC;
|
|
}
|
|
(void)u8RealData;
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief Flash driver check Interrupt
|
|
* @param[in] void
|
|
* @return 1:enable 0:disable
|
|
*/
|
|
static uint8_t FLASHDRIVER_MsrIsOn(void)
|
|
{
|
|
uint8_t u8ReturnValue;
|
|
uint32 u32RegTemp;
|
|
#ifdef USER_MODE_SUPPORT
|
|
__asm volatile(" mrs %0, basepri " : "=r"(u32RegTemp));
|
|
#else
|
|
__asm volatile(" mrs %0, primask " : "=r"(u32RegTemp));
|
|
#endif
|
|
if(0u == (u32RegTemp & 0x00000001U))
|
|
{
|
|
u8ReturnValue = 1U;
|
|
}
|
|
else
|
|
{
|
|
u8ReturnValue = 0U;
|
|
}
|
|
return u8ReturnValue;
|
|
}
|
|
|
|
/* ################################################################################## */
|
|
/* ################################# Global Functions ############################### */
|
|
|
|
/**
|
|
* @brief Flash Driver Function for lock/unlock sector
|
|
*
|
|
* @param u32Address sector address
|
|
* @param bLock 0U-unlock, 1U-lock
|
|
*/
|
|
FLASH_StatusType FLASHDRIVER_LockSector(uint32_t u32Address, FLASH_LOCK_TYPE bLock)
|
|
{
|
|
FLASH_StatusType tRetVal;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
uint32 u32Index = 0;
|
|
uint32 u32Length = 0;
|
|
uint32 u32Temp = 0;
|
|
|
|
/* 1 bank contains more than 256KB, used FB_CPELCK for first and last 256KB used FB_FPELCK */
|
|
if ((u32Address <= (PFLASH_ADDR_START + PFLASH_SIZE)) && (u32Address >= PFLASH_ADDR_START))
|
|
{
|
|
/* PFLASH bank index */
|
|
u32Index = (u32Address - PFLASH_ADDR_START) / PFLASH_BANK_SIZE;
|
|
u32Length = ((u32Address - PFLASH_ADDR_START) % PFLASH_BANK_SIZE);
|
|
if (u32Length < (PFLASH_BANK_SIZE - FLASH_256KB_SIZE))
|
|
{
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON) || (FLASH_FC7300F8MDQ == STD_ON))
|
|
u32Temp = ((uint32)1UL << ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index) >> 16));
|
|
bLock ? (FMC0->FB_CPELCK[u32Index] |= u32Temp) : ((FMC0->FB_CPELCK[u32Index] &= ~u32Temp));
|
|
#elif((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
if(u32Index < 2)
|
|
{
|
|
u32Temp = ((uint32)1UL << ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index) >> 16));
|
|
bLock ? (FMC0->FB_CPELCK[u32Index] |= u32Temp) : ((FMC0->FB_CPELCK[u32Index] &= ~u32Temp));
|
|
}
|
|
else
|
|
{
|
|
u32Temp = ((uint32)1UL << ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index) >> 16));
|
|
bLock ? (FMC0->FB_CPELCK[u32Index + 2] |= u32Temp) : ((FMC0->FB_CPELCK[u32Index +2] &= ~u32Temp));
|
|
}
|
|
#endif
|
|
}
|
|
else /* last 256KB */
|
|
{
|
|
u32Temp = ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index - PFLASH_PHANTOM_OFFSET) >> 13);
|
|
u32Temp = ((uint32)1UL << u32Temp);
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON))
|
|
bLock ? (FMC0->FB_FPELCK[u32Index] |= u32Temp) : ((FMC0->FB_FPELCK[u32Index] &= ~u32Temp));
|
|
#elif(FLASH_FC7300F8MDQ == STD_ON)
|
|
if (u32Index <= 5)
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK[u32Index] |= u32Temp) : ((FMC0->FB_FPELCK[u32Index] &= ~u32Temp));
|
|
}
|
|
else if (u32Index == 6)
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK6 |= u32Temp) : ((FMC0->FB_FPELCK6 &= ~u32Temp));
|
|
}
|
|
else if (u32Index == 7)
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK7 |= u32Temp) : ((FMC0->FB_FPELCK7 &= ~u32Temp));
|
|
}
|
|
else
|
|
{}
|
|
#elif((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
if (u32Index < 2)
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK[u32Index] |= u32Temp) : ((FMC0->FB_FPELCK[u32Index] &= ~u32Temp));
|
|
}
|
|
else
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK[u32Index + 2] |= u32Temp) : ((FMC0->FB_FPELCK[u32Index + 2] &= ~u32Temp));
|
|
}
|
|
#endif
|
|
|
|
}
|
|
}
|
|
else if ((u32Address >= DFLASH_ADDR_START) && (u32Address <= DFLASH_ADDR_END))
|
|
{
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON))
|
|
u32Temp = (1UL << ((u32Address - DFLASH_ADDR_START) >> 13));
|
|
bLock ? (FMC0->FB_FPELCK[FLASH_DATA_BLOCK_SELECT0] |= u32Temp) : ((FMC0->FB_FPELCK[FLASH_DATA_BLOCK_SELECT0] &= ~u32Temp));
|
|
#elif(FLASH_FC7300F8MDQ == STD_ON)
|
|
u32Index = (u32Address - DFLASH_ADDR_START) / DFLASH_BANK_SIZE;
|
|
u32Length = ((u32Address - DFLASH_ADDR_START) % DFLASH_BANK_SIZE);
|
|
u32Temp = ((uint32)1UL << ((u32Address - DFLASH_ADDR_START - DFLASH_BANK_SIZE * u32Index) >> 13));
|
|
if (u32Index == 0)
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK8 |= u32Temp) : ((FMC0->FB_FPELCK8 &= ~u32Temp));
|
|
}
|
|
else if (u32Index == 1)
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK9 |= u32Temp) : ((FMC0->FB_FPELCK9 &= ~u32Temp));
|
|
}
|
|
else if (u32Index == 2)
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK10 |= u32Temp) : ((FMC0->FB_FPELCK10 &= ~u32Temp));
|
|
}
|
|
else
|
|
{}
|
|
#elif((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
u32Index = (u32Address - DFLASH_ADDR_START) / DFLASH_BANK_SIZE;
|
|
u32Length = ((u32Address - DFLASH_ADDR_START) % DFLASH_BANK_SIZE);
|
|
u32Temp = ((uint32)1UL << ((u32Address - DFLASH_ADDR_START - DFLASH_BANK_SIZE * u32Index) >> 13));
|
|
if (u32Index == 0)
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK8 |= u32Temp) : ((FMC0->FB_FPELCK8 &= ~u32Temp));
|
|
}
|
|
else if (u32Index == 1)
|
|
{
|
|
bLock ? (FMC0->FB_FPELCK9 |= u32Temp) : ((FMC0->FB_FPELCK9 &= ~u32Temp));
|
|
}
|
|
else
|
|
{}
|
|
#endif
|
|
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief Flash Driver Function for lock/unlock nvr sector
|
|
*
|
|
* @param u32Address sector address
|
|
* @param bLock 0U-unlock, 1U-lock
|
|
* @return none
|
|
*/
|
|
FLASH_StatusType NVRDRIVER_LockSector(uint32_t u32Address, FLASH_LOCK_TYPE bLock)
|
|
{
|
|
FLASH_StatusType tRetVal;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
#if((FLASH_FC7240F2MDS == STD_ON))
|
|
if(((u32Address >= NVR0_FLASH_ADDR_START) && (u32Address <= NVR0_FLASH_ADDR_END)) ||
|
|
((u32Address >= NVR1_FLASH_ADDR_START) && (u32Address <= NVR1_FLASH_ADDR_END)) ||
|
|
((u32Address >= NVR2_FLASH_ADDR_START) && (u32Address <= NVR2_FLASH_ADDR_END)))
|
|
#elif((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
if(((u32Address >= NVR0_FLASH_ADDR_START) && (u32Address <= NVR0_FLASH_ADDR_END)) ||
|
|
((u32Address >= NVR2_FLASH_ADDR_START) && (u32Address <= NVR2_FLASH_ADDR_END)))
|
|
#elif((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7300F8MDQ == STD_ON))
|
|
if((u32Address >= NVR_FLASH_ADDR_START) && (u32Address <= NVR_FLASH_ADDR_END))
|
|
#endif
|
|
{
|
|
if (bLock == FLASH_LOCK)
|
|
{
|
|
FMC0->FN_FPELCK = 0x01;
|
|
}
|
|
else
|
|
{
|
|
FMC0->FN_FPELCK = 0x00;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief Initial Flash api address
|
|
*
|
|
* @return none
|
|
*/
|
|
void FLASHDRIVER_Init(void)
|
|
{
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Flash Driver Function for lock/unlock sector
|
|
*
|
|
* @param pFlashParam flash driver lock/unlock parameter
|
|
* @return ErrorType
|
|
*/
|
|
FLASH_StatusType FLASHDRIVER_Lock(FLASH_Lock_ParamType *pUnlockParam)
|
|
{
|
|
uint32_t u32Addr, u32Length, u32StartAddr;
|
|
FLASH_StatusType tRetVal;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
u32Addr = pUnlockParam->u32Address;
|
|
u32Length = pUnlockParam->u32Length;
|
|
if(PFlash == pUnlockParam->bFlash)
|
|
{
|
|
if((u32Addr >= PFLASH_ADDR_START) && ((u32Addr + u32Length) <= (PFLASH_ADDR_END + 1)))
|
|
{
|
|
u32StartAddr = (u32Addr &~ (PFLASH_ERASE_SECTOR_SIZE - 1));
|
|
for(uint32_t u32Temp = u32StartAddr ; u32Temp < (u32Addr + u32Length); u32Temp += PFLASH_ERASE_SECTOR_SIZE)
|
|
{
|
|
tRetVal = FLASHDRIVER_LockSector(u32Temp, pUnlockParam->bLock);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
}
|
|
}
|
|
else if(DFlash == pUnlockParam->bFlash)
|
|
{
|
|
if((u32Addr >= DFLASH_ADDR_START) && ((u32Addr + u32Length) <= (DFLASH_ADDR_END + 1)))
|
|
{
|
|
u32StartAddr = (u32Addr &~ (DFLASH_ERASE_SECTOR_SIZE - 1));
|
|
for(uint32_t u32Temp = u32StartAddr ; u32Temp < (u32Addr + u32Length); u32Temp += DFLASH_ERASE_SECTOR_SIZE)
|
|
{
|
|
tRetVal = FLASHDRIVER_LockSector(u32Temp, pUnlockParam->bLock);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_ADDR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_INVALID_PARAM;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
#if((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
/**
|
|
* @brief Flash Driver Function for DMA Write
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @param u32DMACount flash DMA count
|
|
* @return ErrorType
|
|
*/
|
|
FLASH_StatusType FLASHDRIVER_DMAWrite(FLASH_HandleType *pFlashHandle, uint32_t u32DMACount)
|
|
{
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
FLASH_StatusType tRetVal;
|
|
uint32_t u32Temp;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
#if(FLASH_FC7300F4MDS_T1C == STD_ON)
|
|
FLASH_API_DMA_TRIG_CFG_TYPE dma_trig_cfg = {.dma_addr_cnt = u32DMACount, .dma_trig_en = FLASH_REG_BIT_CFG_ENABLE};
|
|
#endif
|
|
FLASH_API_DMA_CFG_TYPE dma_cfg = {.dma_allow = 0x01,.dma_en = 0x01, .dma_ie = 0x01};
|
|
FLASH_API_WDG_CFG_TYPE wdg_cfg = {.wen = 0x0};
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_DMA_WRITING;
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_DMA_CFG_FUNC(&dma_cfg);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Wdog_Configure(&wdg_cfg);
|
|
#if(FLASH_FC7300F4MDS_T1C == STD_ON)
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_DMA_TRIG_FUNC(&dma_trig_cfg);
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON))
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_DMA_TRIG_FUNC(u32DMACount);
|
|
#endif
|
|
tRetVal = ((u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED);
|
|
return tRetVal;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Flash Driver Function for DMA Abort
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @return complete count
|
|
*/
|
|
uint32_t FLASHDRIVER_DMAAbort(FLASH_HandleType *pFlashHandle)
|
|
{
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
uint32_t tRetVal;
|
|
|
|
uint32_t u32TryCount = 0;
|
|
while((((*(uint32*)0x40020004) & 0x00008000) != 0x00008000) && (u32TryCount < 10000))
|
|
{
|
|
u32TryCount++;
|
|
}
|
|
u32TryCount = 0;
|
|
while((((*(uint32*)0x40020004) & 0x00008000) != 0x00000000) && (u32TryCount < 10000))
|
|
{
|
|
u32TryCount++;
|
|
}
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_DMA_ADDR_CNT_READ_FUNC(&tRetVal);
|
|
*(uint32*)0x40020078 &= (~0x00001FFF);
|
|
*(uint32*)0x40020078 |= tRetVal;
|
|
|
|
return tRetVal;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @brief Flash Driver Function for Erasing
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @param pFlashParam flash driver erase parameter
|
|
* @return ErrorType
|
|
*/
|
|
FLASH_StatusType FLASHDRIVER_SyncErase(FLASH_HandleType *pFlashHandle, FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
if (NULL == pFlashParam)
|
|
{
|
|
FLASH_ReportDevError(FLASH_SYNC_ERASE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
uint32_t u32Addr, u32Length;
|
|
uint32_t u32TryCount;
|
|
FLASH_API_ERASESECTOR_TYPE tFlash_api_cfg = {0};
|
|
FLASH_StatusType tRetVal;
|
|
uint32_t u32Temp;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
uint8_t u8IsEnInterupt;
|
|
|
|
/* FLASH_DRV_WDG_CFG_T tFlash_wdg_cfg; */
|
|
u32Addr = pFlashParam->u32Address;
|
|
u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.u32Address = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32CurrentAddress = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.pDate = pFlashParam->pData;
|
|
pFlashHandle->tStatus.u32ErrorAdress = 0x0U;
|
|
if(pFlashHandle->tStatus.u32Address <= PFLASH_ADDR_END)
|
|
{
|
|
pFlashHandle->tStatus.u32EraseSectorSize = PFLASH_ERASE_SECTOR_SIZE;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.u32EraseSectorSize = DFLASH_ERASE_SECTOR_SIZE;
|
|
}
|
|
tRetVal = FLASH_ERROR_OK;
|
|
tRetVal = FLASHDRIVER_EraseCheck(pFlashParam);
|
|
|
|
if (tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
/* flash watchdog config */
|
|
/* tFlash_wdg_cfg.time = FLASH_WDG_TIMEOUT_SELECT3; */
|
|
/* tFlash_wdg_cfg.wen = FLASH_WDG_ENABLE; */
|
|
/* tFlash_wdg_cfg.wint_en = FLASH_WDG_INT_DISABLE; */
|
|
/* (s_pFlashDriver_FuncHeader)->FLASH_DRV_Wdog_Configure(&tFlash_wdg_cfg); */
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_ENABLE_HOLD_CFG(1);
|
|
/* loop erase */
|
|
for (pFlashHandle->tStatus.u32CurrentAddress = u32Addr; pFlashHandle->tStatus.u32CurrentAddress < u32Addr + u32Length;
|
|
pFlashHandle->tStatus.u32CurrentAddress += pFlashHandle->tStatus.u32EraseSectorSize)
|
|
{
|
|
if(NULL != pFlashHandle->tSettings.pUnlockCallback)
|
|
{
|
|
pFlashHandle->tSettings.pUnlockCallback(pFlashHandle->tStatus.u32CurrentAddress);
|
|
}
|
|
FLASHDRIVER_GetFlashConfig(pFlashHandle->tStatus.u32CurrentAddress, &tFlash_api_cfg);
|
|
/* start erase */
|
|
/* Disable Inetrrupt*/
|
|
u8IsEnInterupt = FLASHDRIVER_MsrIsOn();//0 disable ,1 enable
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsid i");
|
|
}
|
|
if (FLASH_HARDWARE_STATUS_IDLE == (((*(volatile uint32 *)FLASH_HARDWARE_STATUS_ADDR) & FLASH_HARDWARE_STATUS_MASK) >> 16))
|
|
{
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON))
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector(&tFlash_api_cfg, FLASH_API_DISABLE, FLASH_API_SIZE);
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector(&tFlash_api_cfg);
|
|
#endif
|
|
tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED;
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_FAILED;
|
|
}
|
|
/* Recover Inetrrupt*/
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsie i");
|
|
}
|
|
|
|
/* check erase operation valid */
|
|
if(tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
/* check erasing still in progress */
|
|
tRetVal = FLASH_ERROR_FAILED;
|
|
u32TryCount = 0;
|
|
while ((tRetVal != FLASH_ERROR_OK) && (u32TryCount++ < 1000000))
|
|
{
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_HV_Status_Check();
|
|
/* check if finished */
|
|
if (u32Temp != STATUS_HVOP)
|
|
{
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector_Clear();
|
|
tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (tRetVal != FLASH_ERROR_OK)
|
|
{
|
|
/* erasing failed, exit */
|
|
pFlashHandle->tStatus.u32ErrorAdress = pFlashHandle->tStatus.u32CurrentAddress;
|
|
FLASHDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
break;
|
|
}
|
|
FLASHDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
}
|
|
}
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
else
|
|
{
|
|
FLASH_ReportDevError(FLASH_SYNC_ERASE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief Flash Driver Function for Writing
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @param pFlashParam flash driver write parameter
|
|
* @return ErrorType
|
|
*/
|
|
FLASH_StatusType FLASHDRIVER_SyncWrite(FLASH_HandleType *pFlashHandle, FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
if (NULL == pFlashParam)
|
|
{
|
|
FLASH_ReportDevError(FLASH_SYNC_WRITE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
uint32_t u32Addr, u32Length, u32DataAddr, u32AlignLen, u32TempLen;
|
|
/* uint8_t *pTempBuf; */
|
|
uint32_t u32AlignOffset, u32Index, u32Count;
|
|
uint32_t u32TryCount;
|
|
uint8_t u8IsEnInterupt;
|
|
|
|
/* FLASH_DRV_WDG_CFG_T tFlash_wdg_cfg; */
|
|
FLASH_API_PRGM_CFG_TYPE tFlash_api_cfg = {0};
|
|
FLASH_StatusType tRetVal;
|
|
uint32_t u32Temp;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
u32Addr = pFlashParam->u32Address;
|
|
u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.u32Address = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32CurrentAddress = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.pDate = pFlashParam->pData;
|
|
pFlashHandle->tStatus.u32ErrorAdress = 0x0U;
|
|
tRetVal = FLASHDRIVER_WriteCheck(pFlashParam);
|
|
if (tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
/* flash watchdog config */
|
|
/* tFlash_wdg_cfg.time = 0x03UL; */
|
|
/* tFlash_wdg_cfg.wen = 0x01UL; */
|
|
/* tFlash_wdg_cfg.wint_en = FLASH_WDG_INT_DISABLE; */
|
|
/* (s_pFlashDriver_FuncHeader)->FLASH_DRV_Wdog_Configure(&tFlash_wdg_cfg); */
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_ENABLE_HOLD_CFG(1);
|
|
|
|
/* align address, write must align to FLASH_PROGRAM_PAGE_MAX_SIZE */
|
|
u32AlignOffset = u32Addr & (FLASH_PROGRAM_PAGE_MAX_SIZE - 1U);
|
|
u32AlignLen = u32Length + u32AlignOffset;
|
|
u32Count = ((u32AlignLen + (FLASH_PROGRAM_PAGE_MAX_SIZE - 1U)) & ~(FLASH_PROGRAM_PAGE_MAX_SIZE - 1U)) / FLASH_PROGRAM_PAGE_MAX_SIZE;
|
|
u32DataAddr = (uint32_t)pFlashHandle->tStatus.pDate;
|
|
u32TempLen = u32AlignLen;
|
|
|
|
for (u32Index = 0U; u32Index < u32Count; u32Index++)
|
|
{
|
|
/* real write length in this cycle */
|
|
u32TempLen = u32Length + u32AlignOffset;
|
|
u32TempLen = u32TempLen >= FLASH_PROGRAM_PAGE_MAX_SIZE ? FLASH_PROGRAM_PAGE_MAX_SIZE : u32TempLen;
|
|
u32TempLen -= u32AlignOffset;
|
|
|
|
pFlashHandle->tStatus.u32CurrentAddress = u32Addr;
|
|
pFlashHandle->tStatus.u32ProgramSize = u32TempLen;
|
|
|
|
if(NULL != pFlashHandle->tSettings.pUnlockCallback)
|
|
{
|
|
pFlashHandle->tSettings.pUnlockCallback(pFlashHandle->tStatus.u32CurrentAddress);
|
|
}
|
|
|
|
tFlash_api_cfg.dest = pFlashHandle->tStatus.u32CurrentAddress;
|
|
tFlash_api_cfg.size = pFlashHandle->tStatus.u32ProgramSize / 4; /* one data is 4 bytes */
|
|
tFlash_api_cfg.pData = (uint32_t *)u32DataAddr;
|
|
tFlash_api_cfg.wdg_tune = WDG_TUNE_DISABLE;
|
|
tFlash_api_cfg.pgff = FLASH_REG_BIT_CFG_DISABLE;
|
|
|
|
/* next address and length */
|
|
u32Addr += u32TempLen;
|
|
u32DataAddr += u32TempLen;
|
|
u32Length -= u32TempLen;
|
|
|
|
u32AlignOffset = 0U;
|
|
|
|
/* start write */
|
|
/* Disable Inetrrupt*/
|
|
u8IsEnInterupt = FLASHDRIVER_MsrIsOn();//0 disable ,1 enable
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsid i");
|
|
}
|
|
if (FLASH_HARDWARE_STATUS_IDLE == (((*(volatile uint32 *)FLASH_HARDWARE_STATUS_ADDR) & FLASH_HARDWARE_STATUS_MASK) >> 16))
|
|
{
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON))
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Program(&tFlash_api_cfg, FLASH_API_DISABLE, FLASH_API_SIZE);
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Program(&tFlash_api_cfg);
|
|
#endif
|
|
tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED;
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_FAILED;
|
|
}
|
|
/* Recover Inetrrupt*/
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsie i");
|
|
}
|
|
/* check erase operation valid */
|
|
if(tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
/* check write still in progress */
|
|
tRetVal = FLASH_ERROR_FAILED;
|
|
u32TryCount = 0;
|
|
while ((tRetVal != FLASH_ERROR_OK) && (u32TryCount++ < 10000))
|
|
{
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_HV_Status_Check();
|
|
/* check if finished */
|
|
if (u32Temp != STATUS_HVOP)
|
|
{
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Clear();
|
|
tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (tRetVal != FLASH_ERROR_OK)
|
|
{
|
|
/* erasing timeout, exit */
|
|
pFlashHandle->tStatus.u32ErrorAdress = pFlashHandle->tStatus.u32CurrentAddress;
|
|
FLASHDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
break;
|
|
}
|
|
FLASHDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
}
|
|
if(FLASH_ECC_ERROR_NONE != FLASHDRIVER_EccCheck(pFlashHandle))
|
|
{
|
|
tRetVal = FLASH_ERROR_FAILED;
|
|
}
|
|
}
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
else
|
|
{
|
|
FLASH_ReportDevError(FLASH_SYNC_WRITE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief NVR driver erase function
|
|
* warning:Need to configure the NVR correctly, otherwise there is a risk that the chip will become bricked.
|
|
* warning:Need to configure the NVR correctly, otherwise there is a risk that the chip will become bricked.
|
|
* warning:Need to configure the NVR correctly, otherwise there is a risk that the chip will become bricked.
|
|
* .=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-. *
|
|
* | ______ | *
|
|
* | .-" "-. | *
|
|
* | / \ | *
|
|
* | _ | | _ | *
|
|
* | ( \ |, .-. .-. ,| / ) | *
|
|
* | > "=._ | )(__/ \__)( | _.=" < | *
|
|
* | (_/"=._"=._ |/ /\ \| _.="_.="\_) | *
|
|
* | "=._"(_ ^^ _)"_.=" | *
|
|
* | "=\__|IIIIII|__/=" | *
|
|
* | _.="| \IIIIII/ |"=._ | *
|
|
* | _ _.="_.="\ /"=._"=._ _ | *
|
|
* | ( \_.="_.=" `--------` "=._"=._/ ) | *
|
|
* | > _.=" "=._ < | *
|
|
* | (_/ \_) | *
|
|
* | | *
|
|
* '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=' *
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @param pFlashParam contains flash erase function parameter, address is align to sector, and length is align to sector
|
|
* @return ErrorType
|
|
*/
|
|
FLASH_StatusType NVRDRIVER_SyncErase(FLASH_HandleType *pFlashHandle, FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
if (NULL == pFlashParam)
|
|
{
|
|
FLASH_ReportDevError(NVR_SYNC_ERASE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
uint32_t u32Addr, u32Length;
|
|
uint32_t u32TryCount;
|
|
FLASH_StatusType tRetVal;
|
|
uint32_t u32Temp;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
uint8_t u8IsEnInterupt;
|
|
|
|
/* FLASH_DRV_WDG_CFG_T tFlash_wdg_cfg; */
|
|
u32Addr = pFlashParam->u32Address;
|
|
u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.u32Address = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32CurrentAddress = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.pDate = pFlashParam->pData;
|
|
pFlashHandle->tStatus.u32ErrorAdress = 0x0U;
|
|
pFlashHandle->tStatus.u32EraseSectorSize = NVR_ERASE_SECTOR_SIZE;
|
|
tRetVal = NVRDRIVER_EraseCheck(pFlashParam);
|
|
|
|
if (tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_ENABLE_HOLD_CFG(1);
|
|
|
|
/* loop erase */
|
|
for (pFlashHandle->tStatus.u32CurrentAddress = u32Addr; pFlashHandle->tStatus.u32CurrentAddress < u32Addr + u32Length;
|
|
pFlashHandle->tStatus.u32CurrentAddress += NVR_ERASE_SECTOR_SIZE)
|
|
{
|
|
if(NULL != pFlashHandle->tSettings.pUnlockCallback)
|
|
{
|
|
pFlashHandle->tSettings.pUnlockCallback(pFlashHandle->tStatus.u32CurrentAddress);
|
|
}
|
|
/* start erase */
|
|
/* Disable Inetrrupt*/
|
|
u8IsEnInterupt = FLASHDRIVER_MsrIsOn();//0 disable ,1 enable
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsid i");
|
|
}
|
|
if (FLASH_HARDWARE_STATUS_IDLE == (((*(volatile uint32 *)FLASH_HARDWARE_STATUS_ADDR) & FLASH_HARDWARE_STATUS_MASK) >> 16))
|
|
{
|
|
#if (FLASH_FC7240F2MDS == STD_ON)
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseNvr(pFlashHandle->tStatus.u32CurrentAddress, FLASH_API_DISABLE);
|
|
#elif((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON))
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseNvr(FLASH_API_DISABLE);
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
FLASH_API_ERASENVR_TYPE tFlash_api_cfg = {0};
|
|
tFlash_api_cfg.addr = pFlashHandle->tStatus.u32CurrentAddress;
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseNvr(&tFlash_api_cfg);
|
|
#endif
|
|
tRetVal = ((u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED);
|
|
/* check erase operation valid */
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_FAILED;
|
|
}
|
|
/* Recover Inetrrupt*/
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsie i");
|
|
}
|
|
|
|
/* check erase operation valid */
|
|
if(tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
/* check erasing still in progress */
|
|
tRetVal = FLASH_ERROR_FAILED;
|
|
u32TryCount = 0;
|
|
while ((tRetVal != FLASH_ERROR_OK) && (u32TryCount++ < 1000000))
|
|
{
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_HV_Status_Check();
|
|
/* check if finished */
|
|
if (u32Temp != STATUS_HVOP)
|
|
{
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseNvr_Clear();
|
|
tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (tRetVal != FLASH_ERROR_OK)
|
|
{
|
|
/* erase operation failed, exit */
|
|
pFlashHandle->tStatus.u32ErrorAdress = pFlashHandle->tStatus.u32CurrentAddress;
|
|
NVRDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
break;
|
|
}
|
|
NVRDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
}
|
|
}
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
else
|
|
{
|
|
FLASH_ReportDevError(NVR_SYNC_ERASE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief NVR driver write function
|
|
* warning:Need to configure the NVR correctly, otherwise there is a risk that the chip will become bricked.
|
|
* warning:Need to configure the NVR correctly, otherwise there is a risk that the chip will become bricked.
|
|
* warning:Need to configure the NVR correctly, otherwise there is a risk that the chip will become bricked.
|
|
* .=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-. *
|
|
* | ______ | *
|
|
* | .-" "-. | *
|
|
* | / \ | *
|
|
* | _ | | _ | *
|
|
* | ( \ |, .-. .-. ,| / ) | *
|
|
* | > "=._ | )(__/ \__)( | _.=" < | *
|
|
* | (_/"=._"=._ |/ /\ \| _.="_.="\_) | *
|
|
* | "=._"(_ ^^ _)"_.=" | *
|
|
* | "=\__|IIIIII|__/=" | *
|
|
* | _.="| \IIIIII/ |"=._ | *
|
|
* | _ _.="_.="\ /"=._"=._ _ | *
|
|
* | ( \_.="_.=" `--------` "=._"=._/ ) | *
|
|
* | > _.=" "=._ < | *
|
|
* | (_/ \_) | *
|
|
* | | *
|
|
* '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=' *
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @param pFlashParam contains flash write function parameter, address is align to page, and length is align to page
|
|
* @return ErrorType
|
|
*/
|
|
FLASH_StatusType NVRDRIVER_SyncWrite(FLASH_HandleType *pFlashHandle, FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
if (NULL == pFlashParam)
|
|
{
|
|
FLASH_ReportDevError(NVR_SYNC_WRITE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
uint32_t u32Addr, u32Length, u32DataAddr, u32AlignLen, u32TempLen;
|
|
/* uint8_t *pTempBuf; */
|
|
uint32_t u32AlignOffset, u32Index, u32Count;
|
|
uint32_t u32TryCount;
|
|
uint32_t u32HardwareStatus;
|
|
uint8_t u8IsEnInterupt;
|
|
|
|
/* FLASH_DRV_WDG_CFG_T tFlash_wdg_cfg; */
|
|
FLASH_API_PRGM_CFG_TYPE tFlash_api_cfg = {0};
|
|
FLASH_StatusType tRetVal;
|
|
uint32_t u32Temp;
|
|
u32Addr = pFlashParam->u32Address;
|
|
u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.u32Address = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32CurrentAddress = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.pDate = pFlashParam->pData;
|
|
pFlashHandle->tStatus.u32ErrorAdress = 0x0U;
|
|
pFlashParam->u32ErrorAddress = 0x0U;
|
|
tRetVal = NVRDRIVER_WriteCheck(pFlashParam);
|
|
u32HardwareStatus = ((*(volatile uint32 *)FLASH_HARDWARE_STATUS_ADDR) & FLASH_HARDWARE_STATUS_MASK) >> 16;
|
|
if ((tRetVal == FLASH_ERROR_OK) && (u32HardwareStatus == FLASH_HARDWARE_STATUS_IDLE))
|
|
{
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_ENABLE_HOLD_CFG(1);
|
|
/* align address, write must align to FLASH_PROGRAM_PAGE_MAX_SIZE */
|
|
u32AlignOffset = u32Addr & (FLASH_PROGRAM_PAGE_MAX_SIZE - 1U);
|
|
u32AlignLen = u32Length + u32AlignOffset;
|
|
u32Count = ((u32AlignLen + (FLASH_PROGRAM_PAGE_MAX_SIZE - 1U)) & ~(FLASH_PROGRAM_PAGE_MAX_SIZE - 1U)) / FLASH_PROGRAM_PAGE_MAX_SIZE;
|
|
u32DataAddr = (uint32_t)pFlashHandle->tStatus.pDate;
|
|
u32TempLen = u32AlignLen;
|
|
|
|
for (u32Index = 0U; u32Index < u32Count; u32Index++)
|
|
{
|
|
/* real write length in this cycle */
|
|
u32TempLen = u32Length + u32AlignOffset;
|
|
u32TempLen = u32TempLen >= FLASH_PROGRAM_PAGE_MAX_SIZE ? FLASH_PROGRAM_PAGE_MAX_SIZE : u32TempLen;
|
|
u32TempLen -= u32AlignOffset;
|
|
|
|
pFlashHandle->tStatus.u32CurrentAddress = u32Addr;
|
|
pFlashHandle->tStatus.u32ProgramSize = u32TempLen;
|
|
|
|
if(NULL != pFlashHandle->tSettings.pUnlockCallback)
|
|
{
|
|
pFlashHandle->tSettings.pUnlockCallback(pFlashHandle->tStatus.u32CurrentAddress);
|
|
}
|
|
|
|
tFlash_api_cfg.dest = pFlashHandle->tStatus.u32CurrentAddress;
|
|
tFlash_api_cfg.size = pFlashHandle->tStatus.u32ProgramSize / 4; /* one data is 4 bytes */
|
|
tFlash_api_cfg.pData = (uint32_t *)u32DataAddr;
|
|
tFlash_api_cfg.wdg_tune = WDG_TUNE_DISABLE;
|
|
tFlash_api_cfg.pgff = FLASH_REG_BIT_CFG_DISABLE;
|
|
|
|
/* next address and length */
|
|
u32Addr += u32TempLen;
|
|
u32DataAddr += u32TempLen;
|
|
u32Length -= u32TempLen;
|
|
u32AlignOffset = 0U;
|
|
|
|
/* start write */
|
|
/* Disable Inetrrupt*/
|
|
u8IsEnInterupt = FLASHDRIVER_MsrIsOn();//0 disable ,1 enable
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsid i");
|
|
}
|
|
if (FLASH_HARDWARE_STATUS_IDLE == (((*(volatile uint32 *)FLASH_HARDWARE_STATUS_ADDR) & FLASH_HARDWARE_STATUS_MASK) >> 16))
|
|
{
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON))
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Nvr(&tFlash_api_cfg, FLASH_API_DISABLE);
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Nvr(&tFlash_api_cfg);
|
|
#endif
|
|
tRetVal = ((u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED);
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FLASH_ERROR_FAILED;
|
|
}
|
|
/* Recover Inetrrupt*/
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsie i");
|
|
}
|
|
|
|
/* check erase operation valid */
|
|
if(tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
/* check write still in progress */
|
|
tRetVal = FLASH_ERROR_FAILED;
|
|
u32TryCount = 0;
|
|
while ((tRetVal != FLASH_ERROR_OK) && (u32TryCount++ < 10000))
|
|
{
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_HV_Status_Check();
|
|
/* check if finished */
|
|
if (u32Temp != STATUS_HVOP)
|
|
{
|
|
u32Temp = (s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Nvr_Clear();
|
|
tRetVal = (u32Temp == STATUS_SUCCESS) ? FLASH_ERROR_OK : FLASH_ERROR_FAILED;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/* check erase operation valid */
|
|
if (tRetVal != FLASH_ERROR_OK)
|
|
{
|
|
/* write operation failed, exit */
|
|
pFlashHandle->tStatus.u32ErrorAdress = pFlashHandle->tStatus.u32CurrentAddress;
|
|
NVRDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
break;
|
|
}
|
|
NVRDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
}
|
|
}
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
else
|
|
{
|
|
FLASH_ReportDevError(NVR_SYNC_WRITE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
return tRetVal;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief flash driver for erase
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @param pFlashParam flash driver erase parameter
|
|
* @return ErrorType
|
|
*/
|
|
FLASH_StatusType FLASHDRIVER_AsyncErase(FLASH_HandleType *pFlashHandle, FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
if (NULL == pFlashParam)
|
|
{
|
|
FLASH_ReportDevError(FLASH_ASYNC_ERASE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
FLASH_StatusType tRetVal;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
|
|
/* FLASH_DRV_WDG_CFG_T tFlash_wdg_cfg; */
|
|
tRetVal = FLASH_ERROR_OK;
|
|
pFlashParam->u32ErrorAddress = 0x0U;
|
|
tRetVal = FLASHDRIVER_EraseCheck(pFlashParam);
|
|
|
|
if (tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ASYNC_ERASE_PENDING;
|
|
pFlashHandle->tStatus.u32Address = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.u32CurrentAddress = pFlashParam->u32Address;
|
|
if(pFlashHandle->tStatus.u32Address <= PFLASH_ADDR_END)
|
|
{
|
|
pFlashHandle->tStatus.u32EraseSectorSize = PFLASH_ERASE_SECTOR_SIZE;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.u32EraseSectorSize = DFLASH_ERASE_SECTOR_SIZE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
FLASH_ReportDevError(FLASH_ASYNC_ERASE_ID, FLASH_E_PARAM_POINTER);
|
|
#endif
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_PARA_ERROR;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @brief flash driver write a fixed size
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @param pFlashParam flash driver write parameter
|
|
* @return ErrorType
|
|
*/
|
|
FLASH_StatusType FLASHDRIVER_AsyncWrite(FLASH_HandleType *pFlashHandle, FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
if (NULL == pFlashParam)
|
|
{
|
|
FLASH_ReportDevError(FLASH_ASYNC_WRITE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
FLASH_StatusType tRetVal;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
pFlashParam->u32ErrorAddress = 0x0U;
|
|
tRetVal = FLASHDRIVER_WriteCheck(pFlashParam);
|
|
if (tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ASYNC_WRITE_PENDING;
|
|
pFlashHandle->tStatus.u32Address = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.u32CurrentAddress = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.pDate = pFlashParam->pData;
|
|
}
|
|
else
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
FLASH_ReportDevError(FLASH_ASYNC_ERASE_ID, FLASH_E_PARAM_POINTER);
|
|
#endif
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_PARA_ERROR;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief flash driver check current status when erasing
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @return Fls_Status_t return the erase status
|
|
*/
|
|
Fls_Status_t FLASHDRIVER_AsyncEraseMainFunction(FLASH_HandleType *pFlashHandle)
|
|
{
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
Fls_Status_t tRetVal;
|
|
FLASH_API_ERASESECTOR_TYPE tFlash_api_cfg = {0};
|
|
uint8_t u8IsEnInterupt;
|
|
|
|
|
|
if(pFlashHandle->tStatus.eFlsStatus == FLS_ERASING)
|
|
{
|
|
/* check if finished */
|
|
if (STATUS_HVOP == (s_pFlashDriver_FuncHeader)->FLASH_DRV_HV_Status_Check())
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ERASING;
|
|
}
|
|
else
|
|
{
|
|
#if ((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7300F8MDQ == STD_ON))
|
|
if (FLASH_PES_CHECK_MASK == ((s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_PES_CHECK_MASK) & \
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P1(FLASH_PES_CHECK_MASK) & \
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P2(FLASH_PES_CHECK_MASK) & \
|
|
FLASH_PES_CHECK_MASK))
|
|
{
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector_Clear();
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_PES_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P1(FLASH_PES_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_PES_CHECK_MASK);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ERASE_ERROR;
|
|
}
|
|
#elif ((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
if (FLASH_PES_CHECK_MASK == ((s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_PES_CHECK_MASK) & \
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P2(FLASH_PES_CHECK_MASK) & \
|
|
FLASH_PES_CHECK_MASK))
|
|
{
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector_Clear();
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_PES_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_PES_CHECK_MASK);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ERASE_ERROR;
|
|
}
|
|
#elif (FLASH_FC7240F2MDS == STD_ON)
|
|
if (FLASH_PES_CHECK_MASK == ((s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_PES_CHECK_MASK) & FLASH_PES_CHECK_MASK))
|
|
{
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector_Clear();
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_PES_CHECK_MASK);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ERASE_ERROR;
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
if (STATUS_SUCCESS == (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector_Clear())
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ASYNC_ERASE_PENDING;
|
|
FLASHDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
pFlashHandle->tStatus.u32CurrentAddress += pFlashHandle->tStatus.u32EraseSectorSize;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ERASE_ERROR;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(pFlashHandle->tStatus.eFlsStatus == FLS_ASYNC_ERASE_PENDING)
|
|
{
|
|
if(pFlashHandle->tStatus.u32CurrentAddress < (pFlashHandle->tStatus.u32Address + pFlashHandle->tStatus.u32Length))
|
|
{
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_ENABLE_HOLD_CFG(1);
|
|
if(NULL != pFlashHandle->tSettings.pUnlockCallback)
|
|
{
|
|
pFlashHandle->tSettings.pUnlockCallback(pFlashHandle->tStatus.u32CurrentAddress);
|
|
}
|
|
FLASHDRIVER_GetFlashConfig(pFlashHandle->tStatus.u32CurrentAddress, &tFlash_api_cfg);
|
|
/* check erase operation valid */
|
|
/* Disable Inetrrupt*/
|
|
u8IsEnInterupt = FLASHDRIVER_MsrIsOn();//0 disable ,1 enable
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsid i");
|
|
}
|
|
if (FLASH_HARDWARE_STATUS_IDLE == (((*(volatile uint32 *)FLASH_HARDWARE_STATUS_ADDR) & FLASH_HARDWARE_STATUS_MASK) >> 16))
|
|
{
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON))
|
|
if ((s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector(&tFlash_api_cfg, FLASH_API_DISABLE, FLASH_API_SIZE) != STATUS_SUCCESS)
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
if ((s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector(&tFlash_api_cfg) != STATUS_SUCCESS)
|
|
#endif
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ERASE_ERROR;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ERASING;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ERASE_ERROR;
|
|
}
|
|
/* Recover Inetrrupt*/
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsie i");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
|
|
}
|
|
}
|
|
|
|
tRetVal = pFlashHandle->tStatus.eFlsStatus;
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief flash driver check current status when writing
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @return Fls_Status_t return the write status
|
|
*/
|
|
Fls_Status_t FLASHDRIVER_AsyncWriteMainFunction(FLASH_HandleType *pFlashHandle)
|
|
{
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
Fls_Status_t tRetVal;
|
|
FLASH_API_PRGM_CFG_TYPE tFlash_api_cfg = {0};
|
|
uint32_t u32ProgramEndAddr, u32EndAddr;
|
|
uint8_t u8IsEnInterupt;
|
|
|
|
|
|
if(pFlashHandle->tStatus.eFlsStatus == FLS_WRITING)
|
|
{
|
|
/* check if finished */
|
|
if (STATUS_HVOP == (s_pFlashDriver_FuncHeader)->FLASH_DRV_HV_Status_Check())
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITING;
|
|
}
|
|
else
|
|
{
|
|
#if ((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7300F8MDQ == STD_ON))
|
|
if (FLASH_PES_CHECK_MASK == ((s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_PES_CHECK_MASK) & \
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P1(FLASH_PES_CHECK_MASK) & \
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P2(FLASH_PES_CHECK_MASK) & \
|
|
FLASH_PES_CHECK_MASK))
|
|
{
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Clear();
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_PES_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P1(FLASH_PES_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_PES_CHECK_MASK);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITE_ERROR;
|
|
}
|
|
#elif ((FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
if (FLASH_PES_CHECK_MASK == ((s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_PES_CHECK_MASK) & \
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_P2(FLASH_PES_CHECK_MASK) & \
|
|
FLASH_PES_CHECK_MASK))
|
|
{
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Clear();
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_PES_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear_P2(FLASH_PES_CHECK_MASK);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITE_ERROR;
|
|
}
|
|
#elif (FLASH_FC7240F2MDS == STD_ON)
|
|
if (FLASH_PES_CHECK_MASK == ((s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_PES_CHECK_MASK) & FLASH_PES_CHECK_MASK))
|
|
{
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Clear();
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_PES_CHECK_MASK);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITE_ERROR;
|
|
pFlashHandle->tStatus.u32ErrorAdress = pFlashHandle->tStatus.u32CurrentAddress;
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
if (STATUS_SUCCESS == (s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Clear())
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ASYNC_WRITE_PENDING;
|
|
FLASHDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
pFlashHandle->tStatus.pDate += pFlashHandle->tStatus.u32ProgramSize;
|
|
pFlashHandle->tStatus.u32CurrentAddress += pFlashHandle->tStatus.u32ProgramSize;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITE_ERROR;
|
|
pFlashHandle->tStatus.u32ErrorAdress = pFlashHandle->tStatus.u32CurrentAddress;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(pFlashHandle->tStatus.eFlsStatus == FLS_ASYNC_WRITE_PENDING)
|
|
{
|
|
if(pFlashHandle->tStatus.u32CurrentAddress < (pFlashHandle->tStatus.u32Address + pFlashHandle->tStatus.u32Length))
|
|
{
|
|
u32EndAddr = pFlashHandle->tStatus.u32Address + pFlashHandle->tStatus.u32Length;
|
|
u32ProgramEndAddr = ((pFlashHandle->tStatus.u32CurrentAddress + FLASH_PROGRAM_PAGE_MAX_SIZE) & ~(FLASH_PROGRAM_PAGE_MAX_SIZE - 1U));
|
|
u32ProgramEndAddr = ((u32ProgramEndAddr > u32EndAddr) ? u32EndAddr : u32ProgramEndAddr);
|
|
pFlashHandle->tStatus.u32ProgramSize = u32ProgramEndAddr - pFlashHandle->tStatus.u32CurrentAddress;
|
|
|
|
tFlash_api_cfg.dest = pFlashHandle->tStatus.u32CurrentAddress;
|
|
tFlash_api_cfg.size = (uint32_t)(pFlashHandle->tStatus.u32ProgramSize) >> 2; /* one data is 4 bytes */
|
|
tFlash_api_cfg.pData = (uint32_t *)(pFlashHandle->tStatus.pDate);
|
|
tFlash_api_cfg.wdg_tune = WDG_TUNE_DISABLE;
|
|
tFlash_api_cfg.pgff = FLASH_REG_BIT_CFG_DISABLE;
|
|
if(NULL != pFlashHandle->tSettings.pUnlockCallback)
|
|
{
|
|
pFlashHandle->tSettings.pUnlockCallback(pFlashHandle->tStatus.u32CurrentAddress);
|
|
}
|
|
/* Disable Inetrrupt*/
|
|
u8IsEnInterupt = FLASHDRIVER_MsrIsOn();//0 disable ,1 enable
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsid i");
|
|
}
|
|
if (FLASH_HARDWARE_STATUS_IDLE == (((*(volatile uint32 *)FLASH_HARDWARE_STATUS_ADDR) & FLASH_HARDWARE_STATUS_MASK) >> 16))
|
|
{
|
|
#if((FLASH_FC7300F8MDT == STD_ON) || (FLASH_FC7300F4MDD_T1B == STD_ON) || (FLASH_FC7300F4MDS_T1B == STD_ON) || (FLASH_FC7240F2MDS == STD_ON))
|
|
if ((s_pFlashDriver_FuncHeader)->FLASH_DRV_Program(&tFlash_api_cfg, FLASH_API_DISABLE, FLASH_API_SIZE) != STATUS_SUCCESS)
|
|
#elif((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
if ((s_pFlashDriver_FuncHeader)->FLASH_DRV_Program(&tFlash_api_cfg) != STATUS_SUCCESS)
|
|
#endif
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITE_ERROR;
|
|
pFlashHandle->tStatus.u32ErrorAdress = pFlashHandle->tStatus.u32CurrentAddress;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITING;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITE_ERROR;
|
|
pFlashHandle->tStatus.u32ErrorAdress = pFlashHandle->tStatus.u32CurrentAddress;
|
|
}
|
|
/* Recover Inetrrupt*/
|
|
if(u8IsEnInterupt == 1)
|
|
{
|
|
__asm(" cpsie i");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
|
|
FLASHDRIVER_EccCheck(pFlashHandle);
|
|
}
|
|
}
|
|
|
|
tRetVal = pFlashHandle->tStatus.eFlsStatus;
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* @brief flash driver interrupt erase
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @param pFlashParam flash driver erase parameter
|
|
* @return none
|
|
*/
|
|
void FLASHDRIVER_InterruptErase(FLASH_HandleType *pFlashHandle, FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
if (NULL == pFlashParam)
|
|
{
|
|
FLASH_ReportDevError(FLASH_INTERRUPT_ERASE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
FLASH_StatusType tRetVal;
|
|
|
|
tRetVal = FLASH_ERROR_OK;
|
|
pFlashParam->u32ErrorAddress = 0x0U;
|
|
tRetVal = FLASHDRIVER_EraseCheck(pFlashParam);
|
|
|
|
if (tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_ERASING;
|
|
pFlashHandle->tStatus.u32Address = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.u32CurrentAddress = pFlashParam->u32Address;
|
|
if(pFlashHandle->tStatus.u32Address <= PFLASH_ADDR_END)
|
|
{
|
|
pFlashHandle->tStatus.u32EraseSectorSize = PFLASH_ERASE_SECTOR_SIZE;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.u32EraseSectorSize = DFLASH_ERASE_SECTOR_SIZE;
|
|
}
|
|
FLASHDRIVER_INTSingleErase(pFlashHandle);
|
|
}
|
|
else
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
FLASH_ReportDevError(FLASH_INTERRUPT_ERASE_ID, FLASH_E_PARAM_POINTER);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief flash driver interrupt write
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @param pFlashParam flash driver write parameter
|
|
* @return none
|
|
*/
|
|
void FLASHDRIVER_InterruptProgram(FLASH_HandleType *pFlashHandle, FLASH_DRIVER_ParamType *pFlashParam)
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
if (NULL == pFlashParam)
|
|
{
|
|
FLASH_ReportDevError(FLASH_INTERRUPT_WRITE_ID, FLASH_E_PARAM_POINTER);
|
|
}
|
|
#endif
|
|
FLASH_StatusType tRetVal;
|
|
tRetVal = FLASH_ERROR_OK;
|
|
pFlashParam->u32ErrorAddress = 0x0U;
|
|
tRetVal = FLASHDRIVER_WriteCheck(pFlashParam);
|
|
if (tRetVal == FLASH_ERROR_OK)
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_WRITING;
|
|
pFlashHandle->tStatus.u32Address = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.u32Length = pFlashParam->u32Length;
|
|
pFlashHandle->tStatus.u32CurrentAddress = pFlashParam->u32Address;
|
|
pFlashHandle->tStatus.pDate = pFlashParam->pData;
|
|
|
|
FLASHDRIVER_INTSingleProgram(pFlashHandle);
|
|
}
|
|
else
|
|
{
|
|
#if FLASH_DEV_ERROR_REPORT == STD_ON
|
|
FLASH_ReportDevError(FLASH_INTERRUPT_WRITE_ID, FLASH_E_PARAM_POINTER);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Close teset mode
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @return none
|
|
*/
|
|
void FLASHDRIVER_Close_Test_Mode(FLASH_HandleType *pFlashHandle)
|
|
{
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Test_Mode_Close();
|
|
}
|
|
|
|
#if ((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
/**
|
|
* @brief Flash Driver Function for enable interrupt
|
|
*
|
|
* @param u32CoreID core id
|
|
* @return none
|
|
*/
|
|
void FLASHDRIVER_EnInterrupt(uint32_t u32CoreID)
|
|
{
|
|
FMC0->FEINTC |= (uint32_t)(0x1<<(u32CoreID+8));
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @brief Process Flash interrupt
|
|
*
|
|
* @param pFlashHandle the Flash instance to use
|
|
* @return process result
|
|
*/
|
|
Fls_ReturnType Fls_CommonProcessInterrupt(FLASH_HandleType *pFlashHandle)
|
|
{
|
|
FLASH_ROM_API_ENTRY_T *const s_pFlashDriver_FuncHeader = s_pFlashDriver[pFlashHandle->eInstance];
|
|
Fls_ReturnType interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
#if((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
FLASH_API_DMA_CFG_TYPE dma_cfg = {.dma_allow = 0x2,.dma_en = 0x0, .dma_ie = 0x2};
|
|
FLASH_API_WDG_CFG_TYPE wdg_cfg = {.wen = 0x0};
|
|
uint32_t u32DMATargetCount, u32DMACount;
|
|
#endif
|
|
if (pFlashHandle->tStatus.eFlsStatus == FLS_WRITING)
|
|
{
|
|
/* check if finished */
|
|
if (STATUS_SUCCESS == (s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Clear())
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_OK;
|
|
FLASHDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
if (pFlashHandle->tStatus.u32CurrentAddress < (pFlashHandle->tStatus.u32Address + pFlashHandle->tStatus.u32Length))
|
|
{
|
|
pFlashHandle->tStatus.pDate += pFlashHandle->tStatus.u32ProgramSize;
|
|
FLASHDRIVER_INTSingleProgram(pFlashHandle);
|
|
}
|
|
else
|
|
{
|
|
if(FLASH_ECC_ERROR_NONE != FLASHDRIVER_EccCheck(pFlashHandle))
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
}
|
|
}
|
|
else if (pFlashHandle->tStatus.eFlsStatus == FLS_ERASING)
|
|
{
|
|
|
|
if (STATUS_SUCCESS == (s_pFlashDriver_FuncHeader)->FLASH_DRV_EraseSector_Clear())
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_OK;
|
|
FLASHDRIVER_LockSector(pFlashHandle->tStatus.u32CurrentAddress, FLASH_LOCK);
|
|
if (pFlashHandle->tStatus.u32CurrentAddress < (pFlashHandle->tStatus.u32Address + pFlashHandle->tStatus.u32Length))
|
|
{
|
|
FLASHDRIVER_INTSingleErase(pFlashHandle);
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
}
|
|
}
|
|
#if((FLASH_FC7300F8MDQ == STD_ON) || (FLASH_FC7300F4MDD_T1C == STD_ON) || (FLASH_FC7300F4MDS_T1C == STD_ON))
|
|
else if(pFlashHandle->tStatus.eFlsStatus == FLS_DMA_WRITING)
|
|
{
|
|
if (FLASH_DMA_DONE_CHECK_MASK == (FLASH_DMA_DONE_CHECK_MASK & (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_DMA_DONE_CHECK_MASK)))
|
|
{
|
|
u32DMACount = (((*(uint32*)0x40020078) & 0x1FFF0000) >> 16);
|
|
u32DMATargetCount = ((*(uint32*)0x40020078) & 0x00001FFF);
|
|
if(FLASH_WDG_CHECK_MASK == (FLASH_WDG_CHECK_MASK & (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_WDG_CHECK_MASK)))
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_DMA_CFG_FUNC(&dma_cfg);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Program_Clear();
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_DMA_DONE_CHECK_MASK);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
|
|
}
|
|
else if(FLASH_PEP_CHECK_MASK == (FLASH_PEP_CHECK_MASK & (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_PEP_CHECK_MASK)))
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_PEP_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_DMA_DONE_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_DMA_CFG_FUNC(&dma_cfg);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
|
|
|
|
}
|
|
else if(FLASH_PES_CHECK_MASK == (FLASH_PES_CHECK_MASK & (s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check(FLASH_PES_CHECK_MASK)))
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_PES_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_DMA_DONE_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_DMA_CFG_FUNC(&dma_cfg);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
|
|
|
|
}
|
|
else if(u32DMACount != u32DMATargetCount)
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_DMA_DONE_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_DMA_CFG_FUNC(&dma_cfg);
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
|
|
}
|
|
else
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_OK;
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Read_Status_Check_Clear(FLASH_DMA_DONE_CHECK_MASK);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_DMA_CFG_FUNC(&dma_cfg);
|
|
(s_pFlashDriver_FuncHeader)->FLASH_DRV_Wdog_Configure(&wdg_cfg);
|
|
|
|
if(FLASH_ECC_ERROR_NONE != FLASHDRIVER_EccCheck(pFlashHandle))
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
}
|
|
else
|
|
{
|
|
pFlashHandle->tStatus.eFlsStatus = FLS_IDLE;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
interrupt_ret = FLASH_INTERRUPT_ERR_NOT_OK;
|
|
}
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
|
|
}
|
|
return interrupt_ret;
|
|
}
|
|
|
|
#endif /* #if FLASH_INSTANCE_COUNT > 0U */
|