PeripheralDriver_Flagchip_F.../Src/module_driver_ldi.c

761 lines
25 KiB
C

/**
* @file module_driver_port.c
* @author Flagchip
* @brief LDI driver type definition and API
* @version 2.0.0
* @date 2025-06-18
*
* SDK Version: 2.6.0
*
* @copyright Copyright (c) 2020-2024 Flagchip Semiconductors Co., Ltd.
*
* @details
*/
/********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2025-06-18 Flagchip0121 N/A Init version
********************************************************************************/
#include "module_driver_ldi.h"
#if LDI_INSTANCE_COUNT > 0U
#ifndef LDI_DEV_ERROR_RELDI
#define LDI_DEV_ERROR_RELDI STD_OFF
#endif
#if LDI_DEV_ERROR_RELDI == STD_ON
#define LDI_ReportDevError(func, error) ReportDevError(LDI_MODULE_ID, func, error)
#endif
#define LDI_FIFO_DEPTH (0x08U)
/********* Local Variables ************/
/** @brief LDI instance list */
static LDI_Type *const s_pLdiInstanceTable[LDI_INSTANCE_COUNT] = LDI_BASE_PTRS;
/***************LDI Global Functions*****************/
/**
* @brief Initialize ldi
*
* @param pLdiHandle pLdiHandle LDI handle for LDI functionality
* @param pInitStruct Initialization structure of ldi
*/
void LDI_Init(LDI_HandleType *pLdiHandle, const LDI_InitType *const pInitStruct)
{
#if LDI_DEV_ERROR_RELDI == STD_ON
if (NULL == pInitStruct || NULL == pLdiHandle)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (pLdiHandle->eInstance >= LDI_INSTANCE_COUNT)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INSTANCE);
}
else if ((FALSE == pInitStruct->tEnChannelfg.bChannel0En))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((LDI_STATE_UNINIT != pLdiHandle->eLdiState))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_STATUS);
}
else if ((pInitStruct->tDisplayfg.tPxdScfg.u32ScfgSignalwinStart >= pInitStruct->tDisplayfg.tPxdScfg.u32ScfgSignalwinEnd) ||
(pInitStruct->tDisplayfg.tPxdScfg.u32ScfgSignalwinStart > LDI_SIGNAL_WINDOW_START_MAX) ||
(pInitStruct->tDisplayfg.tPxdScfg.u32ScfgSignalwinEnd > LDI_SIGNAL_WINDOW_END_MAX))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((pInitStruct->tDisplayfg.tPxdDcfg.u32DcfgSignalwinStart >= pInitStruct->tDisplayfg.tPxdDcfg.u32DcfgSignalwinEnd) ||
(pInitStruct->tDisplayfg.tPxdDcfg.u32DcfgSignalwinStart > LDI_SIGNAL_WINDOW_START_MAX) ||
(pInitStruct->tDisplayfg.tPxdDcfg.u32DcfgSignalwinEnd > LDI_SIGNAL_WINDOW_END_MAX))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((pInitStruct->tDisplayfg.tPxdIcfg.u32IcfgSignalwinStart >= pInitStruct->tDisplayfg.tPxdIcfg.u32IcfgSignalwinEnd) ||
(pInitStruct->tDisplayfg.tPxdIcfg.u32IcfgSignalwinStart > LDI_SIGNAL_WINDOW_START_MAX) ||
(pInitStruct->tDisplayfg.tPxdIcfg.u32IcfgSignalwinEnd > LDI_SIGNAL_WINDOW_END_MAX))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((pInitStruct->tDisplayfg.tPxdGcfg.u32GclkStart > LDI_GCLK_START_MAX) ||
(pInitStruct->tDisplayfg.tPxdGcfg.u32GclkEnd > LDI_GCLK_START_END) ||
(pInitStruct->tDisplayfg.tPxdGcfg.u32GclkPeriod > LDI_GCLK_PERIOD_MAX) )
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((pInitStruct->tDisplayfg.u32PxdRcfg > LDI_RCFG_MAX))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else
{
#endif
LDI_Type *pLdi = s_pLdiInstanceTable[pLdiHandle->eInstance];
uint32 u32LdiCtrlRegValue = 0U;
uint32 u32LdiPxCtrlRegValue = 0U;
uint32 u32LdiPxCtrl2RegValue = 0U;
uint32 u32LdiPxGcfgRegValue = 0U;
uint32 u32LdiPxScfgRegValue = 0U;
uint32 u32LdiPxDcfgRegValue = 0U;
uint32 u32LdiPxIcfgRegValue = 0U;
uint32_t u32Fcr0RegValue = 0U;
uint32_t u32Fcr1RegValue = 0U;
uint32_t u32Fcr2RegValue = 0U;
uint32_t u32Fcr3RegValue = 0U;
uint32 u32ClkCfgValue = 0U;
uint32 u32PinsMask = 0U;
/** config Ldi Dtrl */
LDI_HWA_ClearFIFO(pLdi);
LDI_HWA_ClearFIFOStatus(pLdi);
if (LDI_DCLK_SDR_MODE != pInitStruct->tClkcfg.tDclkcfg.eLdiDclkMode)
{
u32LdiCtrlRegValue |= LDI_CTRL_DDR(1U);
if (FALSE != pInitStruct->tClkcfg.bDdrSdrDelayEn)
{
u32LdiCtrlRegValue |= LDI_CTRL_DDRT(1U);
}
}
else
{
u32LdiCtrlRegValue |= LDI_CTRL_DDR(0U);
if (TRUE != pInitStruct->tClkcfg.bDdrSdrDelayEn)
{
u32LdiCtrlRegValue |= LDI_CTRL_DCLK_INV(1U);
}
}
LDI_HWA_CfgCtrl(pLdi, u32LdiCtrlRegValue);
/** config Ldi Clock */
LDI_HWA_EnFuncClkRef(pLdi);
u32ClkCfgValue |= LDI_CLK_CTRL_FUT_MASK;
switch(pInitStruct->tClkcfg.eDdrSdrDivider)
{
case LDI_DDRSDRPREDIV_BY1:
u32ClkCfgValue |= (LDI_CLK_CTRL_HDC(0x0U)) | (LDI_CLK_CTRL_DEN(0x40U))| (LDI_CLK_CTRL_NUM(0x40U));
break;
case LDI_DDRSDRPREDIV_BY2:
u32ClkCfgValue |= (LDI_CLK_CTRL_HDC(0x0U)) | (LDI_CLK_CTRL_DEN(0x40U))| (LDI_CLK_CTRL_NUM(0x80U));
break;
case LDI_DDRSDRPREDIV_BY4:
u32ClkCfgValue |= (LDI_CLK_CTRL_HDC(0x1U)) | (LDI_CLK_CTRL_DEN(0x20U))| (LDI_CLK_CTRL_NUM(0x80U));
break;
case LDI_DDRSDRPREDIV_BY8:
u32ClkCfgValue |= (LDI_CLK_CTRL_HDC(0x3U)) | (LDI_CLK_CTRL_DEN(0x10U))| (LDI_CLK_CTRL_NUM(0x80U));
break;
case LDI_DDRSDRPREDIV_BY12:
u32ClkCfgValue |= (LDI_CLK_CTRL_HDC(0x5U)) | (LDI_CLK_CTRL_DEN(0x10U)) | (LDI_CLK_CTRL_NUM(0xC0U));
break;
case LDI_DDRSDRPREDIV_BY16:
u32ClkCfgValue |= (LDI_CLK_CTRL_HDC(0x7U)) | (LDI_CLK_CTRL_DEN(0x08U)) | (LDI_CLK_CTRL_NUM(0x80U));
break;
default:
u32ClkCfgValue |= (LDI_CLK_CTRL_HDC(0x0U)) | (LDI_CLK_CTRL_DEN(0x40U)) | (LDI_CLK_CTRL_NUM(0x40U));
break;
}
u32ClkCfgValue |= LDI_CLK_CTRL_GCLKDIV(pInitStruct->tClkcfg.tGclkcfg.eLdiGclkDivider);
if (LDI_GCLK_SDR_CLK == pInitStruct->tClkcfg.tGclkcfg.eLdiGclkSrc)
{
u32ClkCfgValue |= LDI_CLK_CTRL_GCLKMUX(0U);
}
else if (LDI_GCLK_DDR_CLK == pInitStruct->tClkcfg.tGclkcfg.eLdiGclkSrc)
{
u32ClkCfgValue |= LDI_CLK_CTRL_GCLKMUX(1U);
}
else
{
u32ClkCfgValue |= LDI_CLK_CTRL_GCLKMUX(3U);
}
u32ClkCfgValue |= LDI_CLK_CTRL_SSM(pInitStruct->tClkcfg.eSpreadMode);
u32ClkCfgValue |= LDI_CLK_CTRL_SSD(pInitStruct->tClkcfg.eSpreadDirect);
LDI_HWA_SetClkcfg(pLdi, u32ClkCfgValue);
LDI_HWA_EnableClk(pLdi);
/** config Ldi px ctrl */
u32LdiPxCtrlRegValue = (LDI_PX_CTRL_ROWS(pInitStruct->tScreencfg.u32Rows)) | (LDI_PX_CTRL_CHNS(pInitStruct->tScreencfg.u32Channels)) |
(LDI_PX_CTRL_CASCDS(pInitStruct->tScreencfg.u32Cascds)) | (LDI_PX_CTRL_DNUMS(pInitStruct->tScreencfg.u32Dnums));
LDI_HWA_CfgPxCtrl(pLdi, u32LdiPxCtrlRegValue);
/** config Ldi Px Ctrl2 */
u32LdiPxCtrl2RegValue = LDI_PX_CTRL2_GCLK_CONT(1U) | LDI_PX_CTRL2_DCLK_CONT(1U);
LDI_HWA_CfgPxCtrl2(pLdi, u32LdiPxCtrl2RegValue);
/** Ldi clear Tr Size */
LDI_HWA_ClearTrSize(pLdi);
/** config Ldi for special device */
LDI_HWA_CfgPxdRcfg(pLdi, LDI_PXD_RCFG_RCFG(pInitStruct->tDisplayfg.u8PxdRcfg));
uint32_t u32TempGclkPeriod = (pInitStruct->tDisplayfg.tPxdGcfg.u32GclkPeriod > 0x7FFFU) ? 0x7FFFU : pInitStruct->tDisplayfg.tPxdGcfg.u32GclkPeriod;
u32LdiPxGcfgRegValue = LDI_PXD_GCFG_GCLK_START(pInitStruct->tDisplayfg.tPxdGcfg.u8GclkStart) |
LDI_PXD_GCFG_GCLK_PERIOD(u32TempGclkPeriod) |
LDI_PXD_GCFG_GCLK_END(pInitStruct->tDisplayfg.tPxdGcfg.u8GclkEnd) |
LDI_PXD_GCFG_GCLK_RMODE(pInitStruct->tDisplayfg.tPxdGcfg.bGclkRmodeEn);
LDI_HWA_CfgPxdGcfg(pLdi, u32LdiPxGcfgRegValue);
u32LdiPxScfgRegValue = LDI_PXD_SCFG_SET(pInitStruct->tDisplayfg.tPxdScfg.u8ScfgSignalwinStart) |
LDI_PXD_SCFG_CLR(pInitStruct->tDisplayfg.tPxdScfg.u8ScfgSignalwinEnd) |
LDI_PXD_SCFG_CLKM(pInitStruct->tDisplayfg.tPxdScfg.bScfgClockModeEn) |
LDI_PXD_SCFG_REPEAT(pInitStruct->tDisplayfg.tPxdScfg.bScfgRepeatModeEn);
LDI_HWA_CfgPxdScfg(pLdi, u32LdiPxScfgRegValue);
u32LdiPxDcfgRegValue = LDI_PXD_DCFG_SET(pInitStruct->tDisplayfg.tPxdDcfg.u8DcfgSignalwinStart) |
LDI_PXD_DCFG_CLR(pInitStruct->tDisplayfg.tPxdDcfg.u8DcfgSignalwinEnd) |
LDI_PXD_DCFG_CLKM(pInitStruct->tDisplayfg.tPxdDcfg.bDcfgClockModeEn) |
LDI_PXD_DCFG_REPEAT(pInitStruct->tDisplayfg.tPxdDcfg.bDcfgRepeatModeEn);
LDI_HWA_CfgPxdDcfg(pLdi, u32LdiPxDcfgRegValue);
u32LdiPxIcfgRegValue = LDI_PXD_ICFG_SET(pInitStruct->tDisplayfg.tPxdIcfg.u8IcfgSignalwinStart) |
LDI_PXD_ICFG_CLR(pInitStruct->tDisplayfg.tPxdIcfg.u8IcfgSignalwinEnd) |
LDI_PXD_ICFG_CLKM(pInitStruct->tDisplayfg.tPxdIcfg.bIcfgClockModeEn) |
LDI_PXD_ICFG_REPEAT(pInitStruct->tDisplayfg.tPxdIcfg.bIcfgRepeatModeEn);
LDI_HWA_CfgPxdIcfg(pLdi, u32LdiPxIcfgRegValue);
/** config Ldi enable pins */
if (LDI_LSB_FIRST != pInitStruct->eBitOrder)
{
u32PinsMask = 0x1U;
pLdiHandle->tStatus.tChannelState.bChannel0En = TRUE;
u32Fcr0RegValue = LDI_FCR0_EDC(0U) | LDI_FCR0_WMRK(4U);
if (FALSE != pInitStruct->tEnChannelfg.bChannel1En)
{
u32PinsMask |= 0x2U;
pLdiHandle->tStatus.tChannelState.bChannel1En = TRUE;
u32Fcr1RegValue |= LDI_FCR1_EDC(0U) | LDI_FCR0_WMRK(4U);
}
if (FALSE != pInitStruct->tEnChannelfg.bChannel2En)
{
u32PinsMask |= 0x4U;
pLdiHandle->tStatus.tChannelState.bChannel2En = TRUE;
u32Fcr2RegValue |= LDI_FCR2_EDC(0U) | LDI_FCR0_WMRK(4U);
}
if (FALSE != pInitStruct->tEnChannelfg.bChannel3En)
{
u32PinsMask |= 0x8U;
pLdiHandle->tStatus.tChannelState.bChannel3En = TRUE;
u32Fcr3RegValue |= LDI_FCR3_EDC(0U) | LDI_FCR0_WMRK(4U);
}
}
else
{
u32PinsMask = 0x1U;
pLdiHandle->tStatus.tChannelState.bChannel0En = TRUE;
u32Fcr0RegValue |= LDI_FCR0_EDC(1U) | LDI_FCR0_WMRK(4U);
if (FALSE != pInitStruct->tEnChannelfg.bChannel1En)
{
u32PinsMask |= 0x2U;
pLdiHandle->tStatus.tChannelState.bChannel1En = TRUE;
u32Fcr1RegValue |= LDI_FCR1_EDC(1U) | LDI_FCR0_WMRK(4U);
}
if (FALSE != pInitStruct->tEnChannelfg.bChannel2En)
{
u32PinsMask |= 0x4U;
pLdiHandle->tStatus.tChannelState.bChannel2En = TRUE;
u32Fcr2RegValue |= LDI_FCR2_EDC(1U) | LDI_FCR0_WMRK(4U);
}
if (FALSE != pInitStruct->tEnChannelfg.bChannel3En)
{
u32PinsMask |= 0x8U;
pLdiHandle->tStatus.tChannelState.bChannel3En = TRUE;
u32Fcr3RegValue |= LDI_FCR3_EDC(1U) | LDI_FCR0_WMRK(4U);
}
}
LDI_HWA_CfgFcr0(pLdi, u32Fcr0RegValue);
LDI_HWA_CfgFcr1(pLdi, u32Fcr1RegValue);
LDI_HWA_CfgFcr2(pLdi, u32Fcr2RegValue);
LDI_HWA_CfgFcr3(pLdi, u32Fcr3RegValue);
LDI_HWA_EnableChannel(pLdi, u32PinsMask);
/** Enable interrupt */
LDI_HWA_ClearInterruptFlag(pLdi);
pLdiHandle->tStatus.pUpdateCallback = pInitStruct->pUpdateCallback;
pLdiHandle->tStatus.eLdiState = LDI_STATE_IDLE;
pLdiHandle->tStatus.eLdiDisplayState = LDI_DISPLAY_STOP;
#if LDI_DEV_ERROR_RELDI == STD_ON
}
#endif
}
/**
* @brief Deinit ldi
*
* @param pLdiHandle pLdiHandle LDI handle for LDI functionality
*/
void LDI_Deinit(LDI_HandleType *pLdiHandle)
{
#if LDI_DEV_ERROR_RELDI == STD_ON
if (NULL == pLdiHandle)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (pLdiHandle->eInstance >= LDI_INSTANCE_COUNT)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INSTANCE);
}
else if ((LDI_STATE_UNINIT == pLdiHandle->tStatus.eLdiState))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_STATUS);
}
else
{
#endif
LDI_Type *pLdi = s_pLdiInstanceTable[pLdiHandle->eInstance];
/** Reset register */
LDI_HWA_ClearFIFO(pLdi);
LDI_HWA_ClearFIFOStatus(pLdi);
LDI_HWA_CfgCtrl(pLdi, 0x00010000U);
LDI_HWA_CfgClkCtrl(pLdi, 0x00420000U);
LDI_HWA_DisableInterrupt(pLdi);
LDI_HWA_ClearInterruptFlag(pLdi);
LDI_HWA_CfgPxCtrl(pLdi, 0x00000000U);
LDI_HWA_CfgPxCtrl2(pLdi, 0x00000000U);
LDI_HWA_CfgPxStatus(pLdi, 0xFFFFFF00U);
LDI_HWA_CfgPxdRcfg(pLdi, 0x00000000U);
LDI_HWA_CfgPxdGcfg(pLdi, 0x00000000U);
LDI_HWA_CfgPxdScfg(pLdi, 0x00000000U);
LDI_HWA_CfgPxdDcfg(pLdi, 0x00000000U);
LDI_HWA_CfgPxdIcfg(pLdi, 0x00000000U);
LDI_HWA_CfgFcr0(pLdi, 0x00000000U);
LDI_HWA_CfgFcr1(pLdi, 0x00000000U);
LDI_HWA_CfgFcr2(pLdi, 0x00000000U);
LDI_HWA_CfgFcr3(pLdi, 0x00000000U);
/** Reset status */
pLdiHandle->eInstance = LDI0;
pLdiHandle->tStatus.pUpdateCallback = NULL;
pLdiHandle->tStatus.eLdiState = LDI_STATE_UNINIT;
pLdiHandle->tStatus.eLdiDisplayState = LDI_DISPLAY_STOP;
pLdiHandle->tStatus.tChannelState.bChannel0En = FALSE;
pLdiHandle->tStatus.tChannelState.bChannel1En = FALSE;
pLdiHandle->tStatus.tChannelState.bChannel2En = FALSE;
pLdiHandle->tStatus.tChannelState.bChannel3En = FALSE;
#if LDI_DEV_ERROR_RELDI == STD_ON
}
#endif
}
/**
* @brief De-initialize the Ldi instance
*
* @param pLdiHandle pLdiHandle LDI handle for LDI functionality
* @param pUpdateStruct Ldi update data struct
*
* @return LDI_StatesType
*/
LDI_StatesType LDI_Update(LDI_HandleType *pLdiHandle, const LDI_UpdateType *const pUpdateStruct)
{
#if LDI_DEV_ERROR_RELDI == STD_ON
if (NULL == pLdiHandle)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (pLdiHandle->eInstance >= LDI_INSTANCE_COUNT)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INSTANCE);
}
else if ((LDI_STATE_UNINIT == pLdiHandle->tStatus.eLdiState))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_STATUS);
}
else if ((TRUE != pLdiHandle->tStatus.tChannelState.bChannel0En))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (NULL == pUpdateStruct)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((0U != ((pUpdateStruct->u32LdiDatalen) & 0x1U)))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (NULL == pUpdateStruct->pLdiData0)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((NULL == pUpdateStruct->pLdiData1) && (FALSE != pLdiHandle->tStatus.tChannelState.bChannel1En))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((NULL == pUpdateStruct->pLdiData2) && (FALSE != pLdiHandle->tStatus.tChannelState.bChannel2En))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((NULL == pUpdateStruct->pLdiData3) && (FALSE != pLdiHandle->tStatus.tChannelState.bChannel3En))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else
{
#endif
LDI_StatesType eRet = LDI_STATUS_SUCCESS;
if (LDI_STATE_IDLE != pLdiHandle->tStatus.eLdiState)
{
eRet = LDI_STATUS_ERROR;
}
else
{
pLdiHandle->tStatus.eLdiState = LDI_STATE_BUSY;
LDI_Type *pLdi = s_pLdiInstanceTable[pLdiHandle->eInstance];
const uint32_t *pTempData0 = (uint32_t *)pUpdateStruct->pLdiData0;
const uint32_t *pTempData1 = (uint32_t *)pUpdateStruct->pLdiData1;
const uint32_t *pTempData2 = (uint32_t *)pUpdateStruct->pLdiData2;
const uint32_t *pTempData3 = (uint32_t *)pUpdateStruct->pLdiData3;
uint32_t u32LdiTimeOut = 0xFFFFFFFFU;
uint32_t u32Cnt = 0U;
uint32_t u32TrSizeValue = pUpdateStruct->u32LdiDatalen >> 0x1U;
uint32_t u32leftDatalen = pUpdateStruct->u32LdiDatalen & 0x3U;
uint32_t u32Clearlen = ((pUpdateStruct->u32LdiDatalen - u32leftDatalen) >> 2U);
if (TRUE != pLdiHandle->tStatus.tChannelState.bChannel1En)
{
pTempData1 = pTempData0;
}
if (TRUE != pLdiHandle->tStatus.tChannelState.bChannel2En)
{
pTempData2 = pTempData0;
}
if (TRUE != pLdiHandle->tStatus.tChannelState.bChannel3En)
{
pTempData3 = pTempData0;
}
LDI_HWA_ClearFIFO(pLdi);
LDI_HWA_SetTrSize(pLdi, u32TrSizeValue);
LDI_HWA_EnableInterrupt(pLdi);
if (u32Clearlen < 4U )
{
if (0U < u32Clearlen)
{
for (u32Cnt = 0U; u32Cnt < u32Clearlen; u32Cnt++)
{
pLdi->FDR0 = *pTempData0;
pLdi->FDR1 = *pTempData1;
pLdi->FDR2 = *pTempData2;
pLdi->FDR3 = *pTempData3;
pTempData0++;
pTempData1++;
pTempData2++;
pTempData3++;
}
LDI_HWA_UpdateStart(pLdi);
}
}
else
{
for (u32Cnt = 0U; u32Cnt < 4U; u32Cnt++)
{
pLdi->FDR0 = *pTempData0;
pLdi->FDR1 = *pTempData1;
pLdi->FDR2 = *pTempData2;
pLdi->FDR3 = *pTempData3;
pTempData0++;
pTempData1++;
pTempData2++;
pTempData3++;
}
LDI_HWA_UpdateStart(pLdi);
while ((u32Cnt < u32Clearlen) && (0U != u32LdiTimeOut))
{
if (LDI_HWA_GetCh0FifoFillLevel(pLdi) < (LDI_FIFO_DEPTH - 1U))
{
pLdi->FDR0 = *pTempData0;
pLdi->FDR1 = *pTempData1;
pLdi->FDR2 = *pTempData2;
pLdi->FDR3 = *pTempData3;
pTempData0++;
pTempData1++;
pTempData2++;
pTempData3++;
u32Cnt++;
}
u32LdiTimeOut--;
}
}
/** Data len is 2 Byte*/
if (0U < u32leftDatalen)
{
if (LDI_HWA_GetCh0FifoFillLevel(pLdi) < LDI_FIFO_DEPTH)
{
pLdi->FDR0 = (uint16)(*pTempData0);
pLdi->FDR1 = (uint16)(*pTempData1);
pLdi->FDR2 = (uint16)(*pTempData2);
pLdi->FDR3 = (uint16)(*pTempData3);
}
if (0U == u32Clearlen)
{
LDI_HWA_UpdateStart(pLdi);
}
}
u32LdiTimeOut = 0xFFFFFFFFU;
while (0U != u32LdiTimeOut)
{
if (0U != LDI_HWA_GetUpdateFlag(pLdi))
{
pLdiHandle->tStatus.eLdiState = LDI_STATE_IDLE;
LDI_HWA_DisableInterrupt(pLdi);
LDI_HWA_ClearInterruptFlag(pLdi);
LDI_HWA_ClearFIFO(pLdi);
break;
}
u32LdiTimeOut--;
}
if (0U == u32LdiTimeOut)
{
eRet = LDI_STATUS_TIMEOUT;
LDI_HWA_DisableInterrupt(pLdi);
LDI_HWA_ClearInterruptFlag(pLdi);
LDI_HWA_ClearFIFO(pLdi);
}
}
return eRet;
#if LDI_DEV_ERROR_RELDI == STD_ON
}
#endif
}
/**
* @brief Update data in DMA mode (Non-block)
*
* @param pLdiHandle pLdiHandle LDI handle for LDI functionality
* @param pUpdateStruct Ldi update data struct
*
* @return LDI_StatesType
*/
LDI_StatesType LDI_Update_DMA(LDI_HandleType *pLdiHandle, const LDI_UpdateType *const pUpdateStruct)
{
#if LDI_DEV_ERROR_RELDI == STD_ON
if (NULL == pLdiHandle)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (pLdiHandle->eInstance >= LDI_INSTANCE_COUNT)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INSTANCE);
}
else if ((LDI_STATE_UNINIT == pLdiHandle->tStatus.eLdiState))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_STATUS);
}
else if ((TRUE != pLdiHandle->tStatus.tChannelState.bChannel0En))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (NULL == pUpdateStruct)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if ((0U != ((pUpdateStruct->u32LdiDatalen) & 0x1U)))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else
{
#endif
LDI_StatesType eRet = LDI_STATUS_SUCCESS;
if (LDI_STATE_IDLE != pLdiHandle->tStatus.eLdiState)
{
eRet = LDI_STATUS_ERROR;
}
else
{
LDI_Type *pLdi = s_pLdiInstanceTable[pLdiHandle->eInstance];
uint32_t u32TrSizeValue = pUpdateStruct->u32LdiDatalen >> 0x1U;
LDI_HWA_ClearFIFO(pLdi);
LDI_HWA_SetTrSize(pLdi, u32TrSizeValue);
LDI_HWA_EnableDma(pLdi);
LDI_HWA_EnableInterrupt(pLdi);
LDI_HWA_UpdateStart(pLdi);
}
return eRet;
#if LDI_DEV_ERROR_RELDI == STD_ON
}
#endif
}
/**
* @brief Ldi start display
*
* @param pLdiHandle pLdiHandle LDI handle for LDI functionality
*/
void LDI_Dispaly_Start(LDI_HandleType *pLdiHandle)
{
#if LDI_DEV_ERROR_RELDI == STD_ON
if (NULL == pLdiHandle)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (pLdiHandle->eInstance >= LDI_INSTANCE_COUNT)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INSTANCE);
}
else if ((LDI_STATE_UNINIT == pLdiHandle->tStatus.eLdiState))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_STATUS);
}
else
{
#endif
if (LDI_DISPLAY_START != pLdiHandle->tStatus.eLdiDisplayState)
{
LDI_Type *pLdi = s_pLdiInstanceTable[pLdiHandle->eInstance];
LDI_HWA_CfgDisplay(pLdi);
}
#if LDI_DEV_ERROR_RELDI == STD_ON
}
#endif
}
/**
* @brief Ldi stop display
*
* @param pLdiHandle pLdiHandle LDI handle for LDI functionality
*/
void LDI_Dispaly_Stop(LDI_HandleType *pLdiHandle)
{
#if LDI_DEV_ERROR_RELDI == STD_ON
if (NULL == pLdiHandle)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (pLdiHandle->eInstance >= LDI_INSTANCE_COUNT)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INSTANCE);
}
else if ((LDI_STATE_UNINIT == pLdiHandle->tStatus.eLdiState))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_STATUS);
}
else
{
#endif
if (LDI_DISPLAY_STOP != pLdiHandle->tStatus.eLdiDisplayState)
{
LDI_Type *pLdi = s_pLdiInstanceTable[pLdiHandle->eInstance];
LDI_HWA_CfgDisplay(pLdi);
}
#if LDI_DEV_ERROR_RELDI == STD_ON
}
#endif
}
/**
* @brief LDIn Interrupt Handler.
*
* @param pLdiHandle pLdiHandle LDI handle for LDI functionality
*/
void LDIn_IRQHandler(LDI_HandleType *pLdiHandle)
{
#if LDI_DEV_ERROR_RELDI == STD_ON
if (NULL == pLdiHandle)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INPUT);
}
else if (pLdiHandle->eInstance >= LDI_INSTANCE_COUNT)
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_INSTANCE);
}
else if ((LDI_STATE_UNINIT == pLdiHandle->tStatus.eLdiState))
{
LDI_ReportDevError(LDI_InitPins_ID, LDI_E_PARAM_STATUS);
}
else
{
#endif
LDI_Type *pLdi = s_pLdiInstanceTable[pLdiHandle->eInstance];
uint32_t u32LdiTimeOut = 0xFFFFFFFFU;
LDI_HWA_DisableDma(pLdi);
while(0U != u32LdiTimeOut)
{
if (0U != LDI_HWA_GetUpdateFlag(pLdi))
{
pLdiHandle->tStatus.eLdiState = LDI_STATE_IDLE;
LDI_HWA_DisableInterrupt(pLdi);
LDI_HWA_ClearInterruptFlag(pLdi);
LDI_HWA_ClearFIFO(pLdi);
if (NULL != pLdiHandle->tStatus.pUpdateCallback)
{
pLdiHandle->tStatus.pUpdateCallback();
}
break;
}
u32LdiTimeOut--;
}
#if LDI_DEV_ERROR_RELDI == STD_ON
}
#endif
}
#endif