761 lines
25 KiB
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
|
|
|
|
|