198 lines
6.9 KiB
C
198 lines
6.9 KiB
C
/**
|
|
* @file fc7xxx_driver_fmc.c
|
|
* @author Flagchip
|
|
* @brief FC7xxx Fmc driver source code
|
|
* @version 0.1.0
|
|
* @date 2024-1-5
|
|
*
|
|
* @copyright Copyright (c) 2024 Flagchip Semiconductors Co., Ltd.
|
|
*/
|
|
/* ********************************************************************************
|
|
* Revision History:
|
|
*
|
|
* Version Date Initials CR# Descriptions
|
|
* --------- ---------- ------------ ---------- ---------------
|
|
* 0.1.0 2024-1-5 Flagchip120 N/A First version for FC7240
|
|
******************************************************************************** */
|
|
|
|
#include "fc7xxx_driver_fmc.h"
|
|
|
|
/* ################################################################################## */
|
|
/* ####################################### Macro #################################### */
|
|
|
|
|
|
/* ################################################################################## */
|
|
/* ################################ Local Variables ################################# */
|
|
static FMC_Type *const s_apFmcBase[FMC_INSTANCE_COUNT] = FMC_BASE_PTRS;
|
|
|
|
/* ################################################################################## */
|
|
/* ########################### Local Prototype Functions ############################ */
|
|
|
|
|
|
/**
|
|
* \brief FMC PFlash Driver Function for lock/unlock sector
|
|
*
|
|
* \param pFMC FMC instance
|
|
* \param u32Address sector address
|
|
* \param bLock 0U-unlock, 1U-lock
|
|
*/
|
|
static FMC_Lock_StatusType FMCDRIVER_PFlashLockRegion(const FMC_InstanceType eInstance, uint32_t u32Address, uint8_t bLock);
|
|
|
|
/**
|
|
* \brief FMC DFlash Driver Function for lock/unlock sector
|
|
*
|
|
* \param pFMC FMC instance
|
|
* \param u32Address sector address
|
|
* \param bLock 0U-unlock, 1U-lock
|
|
*/
|
|
static FMC_Lock_StatusType FMCDRIVER_DFlashLockRegion(const FMC_InstanceType eInstance, uint32_t u32Address, uint8_t bLock);
|
|
|
|
/* ################################################################################## */
|
|
/* ########################### Global Prototype Functions ########################### */
|
|
|
|
|
|
/* ################################################################################## */
|
|
/* ################################ Local Functions ################################# */
|
|
|
|
/**
|
|
* \brief FMC PFlash Driver Function for lock/unlock sector
|
|
*
|
|
* \param eInstance FMC instance
|
|
* \param u32Address sector address
|
|
* \param bLock 0U-unlock, 1U-lock
|
|
*/
|
|
static FMC_Lock_StatusType FMCDRIVER_PFlashLockRegion(const FMC_InstanceType eInstance, uint32_t u32Address, uint8_t bLock)
|
|
{
|
|
FMC_Type *const pFMC = s_apFmcBase[eInstance];
|
|
FMC_Lock_StatusType tRetVal;
|
|
uint32_t u32Index;
|
|
uint32_t u32Length;
|
|
uint32_t u32Temp;
|
|
|
|
tRetVal = FMC_LOCK_ERROR_OK;
|
|
|
|
/* 1 bank contains more than 256KB, used FB_CPELCK for first and last 256KB used FB_FPELCK */
|
|
if ((u32Address >= PFLASH_ADDR_START) && (u32Address <= (PFLASH_ADDR_START + PFLASH_TOTAL_SIZE)))
|
|
{
|
|
/* 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)) /* first 768KB */
|
|
{
|
|
u32Temp = ((uint32_t)1UL << ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index) >> 16));
|
|
u32Temp = bLock ? (FMC_HWA_GetFBCPELCKValue(pFMC, u32Index) | u32Temp) : (FMC_HWA_GetFBCPELCKValue(pFMC, u32Index) & ~u32Temp);
|
|
FMC_HWA_SetFBCPELCKValue(pFMC, u32Index, u32Temp);
|
|
}
|
|
else /* last 256KB */
|
|
{
|
|
u32Temp = ((u32Address - PFLASH_ADDR_START - PFLASH_BANK_SIZE * u32Index - PFLASH_PHANTOM_OFFSET) >> 13);
|
|
u32Temp = ((uint32_t)1UL << u32Temp);
|
|
u32Temp = bLock ? (FMC_HWA_GetFBFPELCKValue(pFMC, u32Index) | u32Temp) : (FMC_HWA_GetFBFPELCKValue(pFMC, u32Index) & ~u32Temp);
|
|
FMC_HWA_SetFBFPELCKValue(pFMC, u32Index, u32Temp);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FMC_LOCK_ERROR_INVALID_ADDR;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
|
|
/**
|
|
* \brief FMC DFlash Driver Function for lock/unlock sector
|
|
*
|
|
* \param eInstance FMC instance
|
|
* \param u32Address sector address
|
|
* \param bLock 0U-unlock, 1U-lock
|
|
*/
|
|
static FMC_Lock_StatusType FMCDRIVER_DFlashLockRegion(const FMC_InstanceType eInstance, uint32_t u32Address, uint8_t bLock)
|
|
{
|
|
FMC_Type *const pFMC = s_apFmcBase[eInstance];
|
|
FMC_Lock_StatusType tRetVal;
|
|
uint32_t u32Index;
|
|
uint32_t u32Temp;
|
|
tRetVal = FMC_LOCK_ERROR_OK;
|
|
|
|
/* 1 bank contains only 128KB, only used FB_FPELCK */
|
|
u32Index = 2U;
|
|
if ((u32Address >= DFLASH_ADDR_START) && (u32Address <= DFLASH_ADDR_END))
|
|
{
|
|
u32Temp = 1UL << ((u32Address - DFLASH_ADDR_START - DFLASH_BANK0_SIZE * (u32Index - 2U)) >> 13);
|
|
u32Temp = bLock ? (FMC_HWA_GetFBFPELCKValue(pFMC, u32Index) | u32Temp) : (FMC_HWA_GetFBFPELCKValue(pFMC, u32Index) & ~u32Temp);
|
|
FMC_HWA_SetFBFPELCKValue(pFMC, u32Index, u32Temp);
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FMC_LOCK_ERROR_INVALID_ADDR;
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
|
|
/* ################################################################################## */
|
|
/* ################################# Global Functions ############################### */
|
|
|
|
/**
|
|
* \brief FMC Driver Function for flash lock
|
|
*
|
|
* \param pFmcParam FMC driver flash lock parameter
|
|
* \return ErrorType
|
|
*/
|
|
FMC_Lock_StatusType FMCDRIVER_FlashLock(FMC_DRIVER_Lock_ParamType *pFmcParam)
|
|
{
|
|
uint32_t u32Addr, u32Length, u32LockSize, u32TempAddr;
|
|
|
|
FMC_Lock_StatusType tRetVal;
|
|
tRetVal = FMC_LOCK_ERROR_OK;
|
|
|
|
u32Addr = pFmcParam->u32Address;
|
|
u32Length = pFmcParam->u32Length;
|
|
u32LockSize = (pFmcParam->bClass == FMC_Page) ? FLASH_PROGRAM_PAGE_SIZE : FLASH_ERASE_SECTOR_SIZE;
|
|
|
|
/* Address and length should aligned by page/sector */
|
|
if (pFmcParam->u32Address & (u32LockSize - 1U))
|
|
{
|
|
tRetVal = FMC_LOCK_ERROR_INVALID_ADDR;
|
|
pFmcParam->u32ErrorAddress = pFmcParam->u32Address;
|
|
}
|
|
if (pFmcParam->u32Length & (u32LockSize - 1U))
|
|
{
|
|
tRetVal = FMC_LOCK_ERROR_INVALID_SIZE;
|
|
pFmcParam->u32ErrorAddress = pFmcParam->u32Address;
|
|
}
|
|
|
|
if (tRetVal == FMC_LOCK_ERROR_OK)
|
|
{
|
|
for (u32TempAddr = u32Addr; u32TempAddr < u32Addr + u32Length; u32TempAddr += u32LockSize)
|
|
{
|
|
if (pFmcParam->bFlash == FMC_PFlash)
|
|
{
|
|
tRetVal = FMCDRIVER_PFlashLockRegion(pFmcParam->bFMC, u32TempAddr, pFmcParam->bLock);
|
|
}
|
|
else
|
|
{
|
|
tRetVal = FMCDRIVER_DFlashLockRegion(pFmcParam->bFMC, u32TempAddr, pFmcParam->bLock);
|
|
}
|
|
}
|
|
}
|
|
return tRetVal;
|
|
}
|
|
|
|
/**
|
|
* \brief FMC set ota active block
|
|
*
|
|
* \param eInstance FMC instance
|
|
* \param bLock 0U-active block 0, 1U-active block 1
|
|
*/
|
|
void FMCDRIVER_SwapBlock(const FMC_InstanceType eInstance, FMC_API_ACTIVE_BLOCK_TYPE bActive)
|
|
{
|
|
FMC_Type *const pFMC = s_apFmcBase[eInstance];
|
|
if (0U == FMC_HWA_GetOTACtrlValue(pFMC, 0))
|
|
{
|
|
FMC_HWA_SetOTAActive(pFMC, 0, bActive);
|
|
FMC_HWA_SetOTAEnable(pFMC, 0);
|
|
}
|
|
}
|
|
|