499 lines
13 KiB
C
499 lines
13 KiB
C
/**
|
|
* @file fc7xxx_driver_overlay.c
|
|
* @author Flagchip
|
|
* @brief FC7xxx overlay driver type definition and API
|
|
* @version 0.1.0
|
|
* @date 2023-12-25
|
|
*
|
|
* @copyright Copyright (c) 2022 Flagchip Semiconductors Co., Ltd.
|
|
*
|
|
*/
|
|
|
|
/********************************************************************************
|
|
* Revision History:
|
|
*
|
|
* Version Date Initials CR# Descriptions
|
|
* --------- ---------- ------------ ---------- ---------------
|
|
* 0.1.0 2023-12-25 Flagchip0038 N/A First version for FC7240
|
|
********************************************************************************/
|
|
|
|
#include "fc7xxx_driver_overlay.h"
|
|
|
|
typedef void (*Void_Type)(void);
|
|
typedef void (*U32_Type)(uint32_t u32Data);
|
|
typedef void (*SizeEnum_Type)(OVERLAY_OverlaySizeType eSize);
|
|
|
|
static Void_Type const s_aRegionEnDisable[OVERLYA_REGION_CNT] =
|
|
{
|
|
OVERLAY_HWA_OverlayRegion0Disable,
|
|
OVERLAY_HWA_OverlayRegion1Disable,
|
|
OVERLAY_HWA_OverlayRegion2Disable
|
|
};
|
|
|
|
|
|
static Void_Type const s_aRegionEnEnable[OVERLYA_REGION_CNT] =
|
|
{
|
|
OVERLAY_HWA_OverlayRegion0Enable,
|
|
OVERLAY_HWA_OverlayRegion1Enable,
|
|
OVERLAY_HWA_OverlayRegion2Enable
|
|
};
|
|
|
|
static U32_Type const s_aRegionSrc[OVERLYA_REGION_CNT] =
|
|
{
|
|
OVERLAY_HWA_SetOverlayRegion0Src,
|
|
OVERLAY_HWA_SetOverlayRegion1Src,
|
|
OVERLAY_HWA_SetOverlayRegion2Src
|
|
};
|
|
|
|
static U32_Type const s_aRegionDst[OVERLYA_REGION_CNT] =
|
|
{
|
|
OVERLAY_HWA_SetOverlayRegion0Dst,
|
|
OVERLAY_HWA_SetOverlayRegion1Dst,
|
|
OVERLAY_HWA_SetOverlayRegion2Dst
|
|
};
|
|
|
|
static SizeEnum_Type const s_aRegionSize[OVERLYA_REGION_CNT] =
|
|
{
|
|
OVERLAY_HWA_SetOverlayRegion0Size,
|
|
OVERLAY_HWA_SetOverlayRegion1Size,
|
|
OVERLAY_HWA_SetOverlayRegion2Size
|
|
};
|
|
|
|
static OVERLAY_ErrorCallback_Type s_tErrorCallbackFunc;
|
|
|
|
/**
|
|
* @brief Overlay region initial function
|
|
*
|
|
* @param pOverlayInitCfg initial parameters
|
|
* @return ERROR_OK is ok, others are not ok
|
|
*/
|
|
OVERLAY_ErrorType OVERLAY_RegionInit(OVERLAY_OverlayRegionInitType *pOverlayInitCfg)
|
|
{
|
|
OVERLAY_ErrorType eRetval;
|
|
uint32_t u32Index;
|
|
uint32_t u32ErrorInfo;
|
|
|
|
eRetval = OVERLAY_ERROR_OK;
|
|
|
|
/* global overlay Disable */
|
|
OVERLAY_HWA_OverlayDisable();
|
|
|
|
/* loop all region */
|
|
for (u32Index = 0U; (u32Index < OVERLYA_REGION_CNT) && (eRetval == OVERLAY_ERROR_OK); u32Index++)
|
|
{
|
|
/* check overlay region enable */
|
|
if (pOverlayInitCfg->aOverlayRegionEn[u32Index])
|
|
{
|
|
if ((pOverlayInitCfg->aOverlayRegionSrc[u32Index] >= PFLASH_START) &&
|
|
(pOverlayInitCfg->aOverlayRegionSrc[u32Index] <= PFLASH_END) &&
|
|
(pOverlayInitCfg->aOverlayRegionDst[u32Index] >= SRAM_START) &&
|
|
(pOverlayInitCfg->aOverlayRegionDst[u32Index] <= SRAM_END)
|
|
)
|
|
{
|
|
|
|
/* disable region n */
|
|
s_aRegionEnDisable[u32Index]();
|
|
|
|
/* source */
|
|
s_aRegionSrc[u32Index](pOverlayInitCfg->aOverlayRegionSrc[u32Index]);
|
|
|
|
/* dest */
|
|
s_aRegionDst[u32Index](pOverlayInitCfg->aOverlayRegionDst[u32Index]);
|
|
|
|
/* size */
|
|
s_aRegionSize[u32Index](pOverlayInitCfg->aOverlayRegionSize[u32Index]);
|
|
|
|
/* enable region n */
|
|
s_aRegionEnEnable[u32Index]();
|
|
}
|
|
else
|
|
{
|
|
eRetval = OVERLAY_ERROR_ADDR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* disable region n */
|
|
s_aRegionEnDisable[u32Index]();
|
|
}
|
|
|
|
}
|
|
|
|
if (eRetval == OVERLAY_ERROR_OK)
|
|
{
|
|
/* global overlay enable */
|
|
OVERLAY_HWA_OverlayEnable();
|
|
}
|
|
|
|
/* check error flag */
|
|
u32ErrorInfo = OVERLAY_HWA_GetErrorFlag();
|
|
if (u32ErrorInfo)
|
|
{
|
|
eRetval = OVERLAY_ERROR_FLAG;
|
|
}
|
|
|
|
return eRetval;
|
|
}
|
|
|
|
/**
|
|
* @brief De-Init Overlay Region
|
|
*
|
|
* @return ERROR_OK is ok, others are not ok
|
|
*/
|
|
OVERLAY_ErrorType OVERLAY_RegionDeInit(void)
|
|
{
|
|
OVERLAY_ErrorType eRetval;
|
|
uint32_t u32Index;
|
|
|
|
eRetval = OVERLAY_ERROR_OK;
|
|
|
|
/* disable global overlay */
|
|
OVERLAY_HWA_OverlayDisable();
|
|
|
|
for (u32Index = 0U; u32Index < OVERLYA_REGION_CNT; u32Index++)
|
|
{
|
|
/* disable region n */
|
|
s_aRegionEnDisable[u32Index]();
|
|
|
|
/* source */
|
|
s_aRegionSrc[u32Index](0U);
|
|
|
|
/* dest */
|
|
s_aRegionDst[u32Index](0U);
|
|
|
|
/* size */
|
|
s_aRegionSize[u32Index](OVERLAY_OVERLAYSIZE_1KB);
|
|
}
|
|
|
|
return eRetval;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Far initial function
|
|
*
|
|
* @param pFarInitCfg initial parameters
|
|
* @return ERROR_OK is ok, others are not ok
|
|
*/
|
|
OVERLAY_ErrorType OVERLAY_FARInit(OVERLAY_FARInitType *pFarInitCfg)
|
|
{
|
|
OVERLAY_ErrorType eRetval;
|
|
uint32_t u32ErrorInfo;
|
|
|
|
eRetval = OVERLAY_ERROR_OK;
|
|
|
|
if (pFarInitCfg->u32FAREn == 0U)
|
|
{
|
|
|
|
/* disable far */
|
|
OVERLAY_HWA_FARDisable();
|
|
}
|
|
else
|
|
{
|
|
/* must align to 64KB, */
|
|
if ((pFarInitCfg->u32FARSize <= OVERLAY_FAR_SIZE_MAX) &&
|
|
((pFarInitCfg->u32FARSize & OVERLAY_FAR_SIZE_MASK) == 0U)
|
|
)
|
|
{
|
|
if ((pFarInitCfg->u32FARDst >= PFLASH_START) &&
|
|
(pFarInitCfg->u32FARDst <= PFLASH_END)
|
|
)
|
|
{
|
|
/* disable far */
|
|
OVERLAY_HWA_FARDisable();
|
|
|
|
/* set far dest */
|
|
OVERLAY_HWA_SetFarDst(pFarInitCfg->u32FARDst);
|
|
/* set far size */
|
|
OVERLAY_HWA_SetFarSize(pFarInitCfg->u32FARSize / OVERLAY_FAR_SIZE_ALIGN - 1);
|
|
/* disable enable */
|
|
OVERLAY_HWA_FAREnable();
|
|
}
|
|
else
|
|
{
|
|
eRetval = OVERLAY_ERROR_ADDR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
eRetval = OVERLAY_ERROR_SIZE;
|
|
}
|
|
}
|
|
|
|
if (eRetval == OVERLAY_ERROR_OK)
|
|
{
|
|
/* enable far */
|
|
OVERLAY_HWA_FAREnable();
|
|
}
|
|
|
|
|
|
/* check error flag */
|
|
u32ErrorInfo = OVERLAY_HWA_GetErrorFlag();
|
|
if (u32ErrorInfo)
|
|
{
|
|
eRetval = OVERLAY_ERROR_FLAG;
|
|
}
|
|
|
|
|
|
return eRetval;
|
|
}
|
|
|
|
/**
|
|
* @brief De-Init FAR Region
|
|
*
|
|
* @return ERROR_OK is ok, others are not ok
|
|
*/
|
|
OVERLAY_ErrorType OVERLAY_FARDeInit(void)
|
|
{
|
|
OVERLAY_ErrorType eRetval;
|
|
|
|
eRetval = OVERLAY_ERROR_OK;
|
|
|
|
/* disable global far */
|
|
OVERLAY_HWA_FARDisable();
|
|
|
|
/* set far dest */
|
|
OVERLAY_HWA_SetFarDst(0x01000000U);
|
|
/* set far size */
|
|
OVERLAY_HWA_SetFarSize(0U);
|
|
|
|
return eRetval;
|
|
}
|
|
|
|
/**
|
|
* @brief Enable or Disable Interrupt
|
|
*
|
|
* @param pInterruptCfg interrupt config parameter
|
|
*/
|
|
void OVERLAY_SetInterrupt(OVERLAY_InterruptType *pInterruptCfg)
|
|
{
|
|
if (pInterruptCfg->bEnableInterrupt)
|
|
{
|
|
OVERLAY_HWA_ErrorInterruptEnable();
|
|
s_tErrorCallbackFunc = pInterruptCfg->pCallBack;
|
|
}
|
|
else
|
|
{
|
|
OVERLAY_HWA_ErrorInterruptDisable();
|
|
s_tErrorCallbackFunc = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Get Error Info
|
|
*
|
|
* @param pErrorInfo error info point
|
|
*/
|
|
void OVERLAY_GetErrorInfo(OVERLAY_ErrorInfoType *pErrorInfo)
|
|
{
|
|
uint32_t u32ErrorInfo;
|
|
u32ErrorInfo = OVERLAY_HWA_GetErrorFlag();
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_FAR_SIZE_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_FAR_SIZE_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_FAR_SIZE_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_FAR_DST_OVERFLOW_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_FAR_DST_OVERFLOW_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_FAR_DST_OVERFLOW_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_FAR_DST_NO_FLASH_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_FAR_DST_NO_FLASH_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_FAR_DST_NO_FLASH_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_D_CROS_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION2_D_CROS_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION2_D_CROS_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_S_CROS_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION2_S_CROS_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION2_S_CROS_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_SIZE_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION2_SIZE_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION2_SIZE_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_DST_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION2_DST_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION2_DST_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION2_SRC_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION2_SRC_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION2_SRC_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_D_CROS_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION1_D_CROS_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION1_D_CROS_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_S_CROS_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION1_S_CROS_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION1_S_CROS_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_SIZE_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION1_SIZE_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION1_SIZE_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_DST_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION1_DST_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION1_DST_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION1_SRC_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION1_SRC_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION1_SRC_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_D_CROS_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION0_D_CROS_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION0_D_CROS_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_S_CROS_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION0_S_CROS_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION0_S_CROS_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_SIZE_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION0_SIZE_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION0_SIZE_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_DST_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION0_DST_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION0_DST_INTR = 0U;
|
|
}
|
|
|
|
if (u32ErrorInfo & AHB_OVERLAY_INTR_FLAG_REGION0_SRC_INTR_MASK)
|
|
{
|
|
pErrorInfo->bError_REGION0_SRC_INTR = 1U;
|
|
}
|
|
else
|
|
{
|
|
pErrorInfo->bError_REGION0_SRC_INTR = 0U;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Clear Error Info
|
|
*
|
|
* @param pErrorInfo error info point
|
|
*/
|
|
void OVERLAY_ClrErrorInfo(OVERLAY_ErrorInfoType *pErrorInfo)
|
|
{
|
|
uint32_t u32ErrorInfo;
|
|
|
|
u32ErrorInfo = AHB_OVERLAY_INTR_FLAG_FAR_SIZE_INTR(pErrorInfo->bError_FAR_SIZE_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_FAR_DST_OVERFLOW_INTR(pErrorInfo->bError_FAR_DST_OVERFLOW_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_FAR_DST_NO_FLASH_INTR(pErrorInfo->bError_FAR_DST_NO_FLASH_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_D_CROS_INTR(pErrorInfo->bError_REGION2_D_CROS_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_S_CROS_INTR(pErrorInfo->bError_REGION2_S_CROS_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_SIZE_INTR(pErrorInfo->bError_REGION2_SIZE_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_DST_INTR(pErrorInfo->bError_REGION2_DST_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION2_SRC_INTR(pErrorInfo->bError_REGION2_SRC_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_D_CROS_INTR(pErrorInfo->bError_REGION1_D_CROS_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_S_CROS_INTR(pErrorInfo->bError_REGION1_S_CROS_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_SIZE_INTR(pErrorInfo->bError_REGION1_SIZE_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_DST_INTR(pErrorInfo->bError_REGION1_DST_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION1_SRC_INTR(pErrorInfo->bError_REGION1_SRC_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_D_CROS_INTR(pErrorInfo->bError_REGION0_D_CROS_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_S_CROS_INTR(pErrorInfo->bError_REGION0_S_CROS_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_SIZE_INTR(pErrorInfo->bError_REGION0_SIZE_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_DST_INTR(pErrorInfo->bError_REGION0_DST_INTR);
|
|
u32ErrorInfo |= AHB_OVERLAY_INTR_FLAG_REGION0_SRC_INTR(pErrorInfo->bError_REGION0_SRC_INTR);
|
|
|
|
OVERLAY_HWA_ClrErrorFlag(u32ErrorInfo);
|
|
}
|
|
/**
|
|
* @brief Call Me in Overlay Error interrupt handler
|
|
*
|
|
*/
|
|
void OVERLAY_ErrorInterruptRoutine(void)
|
|
{
|
|
OVERLAY_ErrorInfoType tErrorInfo;
|
|
if (s_tErrorCallbackFunc != NULL)
|
|
{
|
|
OVERLAY_GetErrorInfo(&tErrorInfo);
|
|
s_tErrorCallbackFunc(tErrorInfo);
|
|
}
|
|
}
|