PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_overlay.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);
}
}