PeripheralDriver_Flagchip_F.../Src/fc7xxx_driver_fciic.c

818 lines
23 KiB
C
Raw Blame History

/**
* @file fc7xxx_driver_fciic.c
* @author Flagchip
* @brief FC7xxx FCIIC driver type definition and API
* @version 0.1.0
* @date 2022-12-31
*
* @copyright Copyright (c) 2023 Flagchip Semiconductors Co., Ltd.
*
*/
/* ********************************************************************************
* Revision History:
*
* Version Date Initials CR# Descriptions
* --------- ---------- ------------ ---------- ---------------
* 0.1.0 2024/1/10 qxw0095 N/A First version for FC7240
******************************************************************************** */
#include "fc7xxx_driver_fciic.h"
#include "interrupt_manager.h"
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
/* #define FCIIC_RX_FIFO */
/* iic instance value */
static FCIIC_Type *const s_aFCIIC_InstanceTable[FCIIC_INSTANCE_COUNT] = FCIIC_BASE_PTRS;
/* store notify callback function point */
static FCIIC_ErrorInterrupt_CallBackType s_aFCIIC_ErrorNotifyTable[FCIIC_INSTANCE_COUNT] = {NULL};
static FCIIC_RxInterrupt_CallBackType s_aFCIIC_RxNotifyTable[FCIIC_INSTANCE_COUNT] = {NULL};
#ifdef FCIIC_RX_ALL_POLLING
/* check every pFciic instance whether is used */
static uint8_t s_aFCIIC_IicMasterUsed[FCIIC_INSTANCE_COUNT];
static uint8_t s_aFCIIC_IicSlaveUsed[FCIIC_INSTANCE_COUNT];
#endif
/* ################################################################################## */
/* ########################### Local Prototype Functions ############################ */
#if 0
static void CheckAndClear(FCIIC_Type *pFciic);
#endif
static void FCIIC_LL_MasterIRQnHandler(uint8_t u8IicIndex);
static void FCIIC_LL_SlaveIRQnHandler(uint8_t u8IicIndex);
static uint8_t FCIIC_Init_Master(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg);
static uint8_t FCIIC_Init_Slave(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg);
/* ################################################################################## */
/* ########################### Global Prototype Functions ########################### */
void FCIIC0_IRQHandler(void);
void FCIIC1_IRQHandler(void);
/* ################################################################################## */
/* ################################ Local Functions ################################# */
#if 0
static void CheckAndClear(FCIIC_Type *pFciic)
{
FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_EPF_STATUS);
FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_SDF_STATUS);
FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_NDF_STATUS);
FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_FEF_STATUS);
FCIIC_Master_HwA_CheckClearStatus(pFciic, FCIIC_MSR_ALF_STATUS);
}
#endif
/***************************************************
* FCIIC_LL_MasterIRQnHandler
* @detail: Iic n interrupt process
*
* param in : u8IicIndex, 0,1,2,3
* param out: none
*
* return : none
* ************************************************/
static void FCIIC_LL_MasterIRQnHandler(uint8_t u8IicIndex)
{
/* uint8_t iic_status; */
uint8_t u8RetVal;
FCIIC_RxDataType pRxData;
uint32_t u32ErrorValue;
/* check pFciic receive data */
u8RetVal = FCIIC_Master_Receive(u8IicIndex, &pRxData);
if ((s_aFCIIC_RxNotifyTable[u8IicIndex] != NULL) && (u8RetVal == 0U))
{
s_aFCIIC_RxNotifyTable[u8IicIndex](u8IicIndex, &pRxData);
}
/* check error */
u32ErrorValue = FCIIC_Master_GetError(u8IicIndex);
if ((u32ErrorValue != 0U) && (s_aFCIIC_ErrorNotifyTable[u8IicIndex] != NULL))
{
s_aFCIIC_ErrorNotifyTable[u8IicIndex](u8IicIndex, 1U, u32ErrorValue);
FCIIC_Master_ClrError(u8IicIndex);
}
}
/***************************************************
* FCIIC_LL_SlaveIRQnHandler
* @detail: Iic n interrupt process
*
* param in : u8IicIndex, 0,1,2,3
* param out: none
*
* return : none
* ************************************************/
static void FCIIC_LL_SlaveIRQnHandler(uint8_t u8IicIndex)
{
/* uint8_t iic_status; */
uint8_t u8RetVal;
FCIIC_RxDataType pRxData;
uint32_t u32ErrorValue;
/* check pFciic receive data */
u8RetVal = FCIIC_Slave_Receive(u8IicIndex, &pRxData);
if ((s_aFCIIC_RxNotifyTable[u8IicIndex] != NULL) && (u8RetVal == 0U))
{
s_aFCIIC_RxNotifyTable[u8IicIndex](u8IicIndex, &pRxData);
}
/* check error */
u32ErrorValue = FCIIC_Slave_GetError(u8IicIndex);
if ((u32ErrorValue != 0U) && (s_aFCIIC_ErrorNotifyTable[u8IicIndex] != NULL))
{
s_aFCIIC_ErrorNotifyTable[u8IicIndex](u8IicIndex, 0U, u32ErrorValue);
FCIIC_Slave_ClrError(u8IicIndex);
}
}
/***************************************************
* FCIIC_Init_Master
* @detail: Iic device master mode initial
*
* param in : pInitCfg, pFciic initial config parameters
* structure address
* param out: none
*
* return : 0 is ok, others are not ok
* ************************************************/
static uint8_t FCIIC_Init_Master(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg)
{
uint32_t u32TempMcr, u32TempMder, u32TempMcfgr0, u32TempMcfgr1, u32TempMcfgr2, u32TempMcfgr3, u32TempMccr0;
uint32_t u32TempMFCR;
FCIIC_Type *pFciic;
uint32_t u32ClkSrcHz;
uint32_t u32FreqDeltaCur, u32FreqDeltaOld;
uint32_t u32FreqDesired, u32FreqCur;
uint32_t u32Prescale, u8PrescaleTemp;
uint32_t u32CLKHI, u32CLKHITemp;
uint32_t u32CLKLO, u32CLKLOTemp;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
u32ClkSrcHz = pInitCfg->u32ClkSrcHz;
u32FreqDesired = pInitCfg->u32Frequency;
u32FreqDeltaOld = u32FreqDesired;
/* SCL_LATENCY is defined as ROUNDDOWN ((2 + FILTSCL + SCL_RISETIME) / (2 ^ PRESCALE)) */
/* CLKLO: Minimum value is 0x3 */
/* CLKHI: Minimum value is 0x1 */
/* SCL clock period: (CLKHI + CLKLO + 2 + SCL_LATENCY) <20><> (2 ^ PRESCALE) <20><> function clock period */
for(u32CLKHITemp=1U; (u32CLKHITemp < 63U); u32CLKHITemp++)
{
for(u32CLKLOTemp=3U; (u32CLKLOTemp < 63U); u32CLKLOTemp++)
{
/* get the linear prescale */
for (u8PrescaleTemp = 0U; u8PrescaleTemp < 8U; u8PrescaleTemp++)
{
u32FreqCur = u32ClkSrcHz / Fc_Power(2U, (uint32_t)u8PrescaleTemp)/(u32CLKHITemp+u32CLKLOTemp+2U);
/* If the current frequency is less than the desired frequency,
* compare the delta with the previous one and select the parameter with the smallest delta
* */
if(u32FreqCur <= u32FreqDesired)
{
u32FreqDeltaCur = u32FreqDesired - u32FreqCur;
if (u32FreqDeltaCur < u32FreqDeltaOld)
{
u32FreqDeltaOld = u32FreqDeltaCur;
u32Prescale = u8PrescaleTemp;
u32CLKHI = u32CLKHITemp;
u32CLKLO = u32CLKLOTemp;
}
break;
}
}
if(u32FreqDeltaOld == 0U)
{
break;
}
}
if(u32FreqDeltaOld==0U)
{
break;
}
}
u32TempMcr = FCIIC_MCR_RRF(0U) |
FCIIC_MCR_RTF(0U) |
FCIIC_MCR_DBGEN(0U) |
FCIIC_MCR_RST(0U) |
FCIIC_MCR_MEN(1U); /* master enable */
u32TempMder = FCIIC_MDER_RDDE(pInitCfg->bEnDma) | /* enable receive dma */
FCIIC_MDER_TDDE(pInitCfg->bEnDma); /* enable transmit dma */
u32TempMcfgr0 = FCIIC_MCFGR0_RDMO(0U) |
FCIIC_MCFGR0_TRGEN(0U);
u32TempMcfgr1 = FCIIC_MCFGR1_PINCFG(0U) | /* 0=open drain; 1=push-pull mode */
FCIIC_MCFGR1_MATCFG(0U) |
FCIIC_MCFGR1_TIMECFG(0U) |
FCIIC_MCFGR1_IGNACK(1U) |
FCIIC_MCFGR1_AUTOSTOP(0U) |
FCIIC_MCFGR1_PRESCALE(u32Prescale); /* Prescaler = 2^n */
u32TempMcfgr2 = FCIIC_MCFGR2_FILTSDA(0U) |
FCIIC_MCFGR2_FILTSCL(0U) |
FCIIC_MCFGR2_BUSIDLE(0U);
u32TempMcfgr3 = FCIIC_MCFGR3_PINLOW(0U);
u32TempMccr0 = FCIIC_MCCR_DATAVD(0x09U) |
FCIIC_MCCR_SETHOLD(0x13U) |
FCIIC_MCCR_CLKHI(u32CLKHI) |
FCIIC_MCCR_CLKLO(u32CLKLO); /* 0x09131327; */
u32TempMFCR = FCIIC_MFCR_TXWATER(pInitCfg->bTxFifoWMrk) | FCIIC_MFCR_RXWATER(pInitCfg->bRxFifoWMrk);
FCIIC_HWA_SetMder(pFciic, u32TempMder);
FCIIC_HWA_SetMCFGR0(pFciic, u32TempMcfgr0);
FCIIC_HWA_SetMCFGR1(pFciic, u32TempMcfgr1);
FCIIC_HWA_SetMCFGR2(pFciic, u32TempMcfgr2);
FCIIC_HWA_SetMCFGR3(pFciic, u32TempMcfgr3);
FCIIC_HWA_SetMCCR(pFciic, u32TempMccr0);
FCIIC_HWA_SetMFCR(pFciic, u32TempMFCR);
FCIIC_HWA_SetMcr(pFciic, u32TempMcr); /* | FCIIC_MCR_RRF_MASK | FCIIC_MCR_RTF_MASK | FCIIC_MCR_DBGEN_MASK | FCIIC_MCR_RST_MASK; */
#ifdef FCIIC_INIT_WAITRESET
u8RetVal = 1;
while (u8RetVal)
{
u8RetVal = (pFciic->MCR & FCIIC_MCR_RST_MASK) >> FCIIC_MCR_RST_SHIFT;
pFciic->MCR = u32TempMcr;
}
#endif
return 0U;
}
/***************************************************
* FCIIC_DeInit_Master
* @detail: Iic device master mode de-initial
*
* param in : u8IicIndex
* param out: none
*
* return : 0 is ok, others are not ok
* ************************************************/
static uint8_t FCIIC_DeInit_Master(uint8_t u8IicIndex)
{
uint32_t u32TempMcr, u32TempMder;
FCIIC_Type *pFciic;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
u32TempMcr = FCIIC_MCR_RRF(0U) |
FCIIC_MCR_RTF(0U) |
FCIIC_MCR_DBGEN(0U) |
FCIIC_MCR_RST(0U) |
FCIIC_MCR_MEN(0U); /* master enable */
u32TempMder = FCIIC_MDER_RDDE(0U) | /* disable receive dma */
FCIIC_MDER_TDDE(0U); /* disable transmit dma */
FCIIC_HWA_SetMder(pFciic, u32TempMder);
FCIIC_HWA_SetMcr(pFciic, u32TempMcr); /* | FCIIC_MCR_RRF_MASK | FCIIC_MCR_RTF_MASK | FCIIC_MCR_DBGEN_MASK | FCIIC_MCR_RST_MASK; */
return 0U;
}
/***************************************************
* FCIIC_Init_Slave
* @detail: Iic device master mode initial
*
* param in : u8IicIndex
* param out: none
*
* return : 0 is ok, others are not ok
* ************************************************/
static uint8_t FCIIC_Init_Slave(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg)
{
uint32_t u32TempScr, u32TempSder, u32TempScfgr1, u32TempScfgr2, u32TempSamr;
FCIIC_Type *pFciic;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
u32TempScr = FCIIC_SCR_FILTEN(0U) |
FCIIC_SCR_RST(0U) |
FCIIC_SCR_SEN(1U); /* slave enable */
u32TempSder = FCIIC_SDER_AVDE(pInitCfg->bEnDma) |
FCIIC_SDER_RDDE(pInitCfg->bEnDma) | /* enable receive dma */
FCIIC_SDER_TDDE(pInitCfg->bEnDma); /* enable transmit dma */
u32TempScfgr1 = FCIIC_SCFGR1_ADDRCFG(0U) | /* Address Configuration, 7bit */
FCIIC_SCFGR1_HSMEN(0U) |
FCIIC_SCFGR1_IGNACK(1U) |
FCIIC_SCFGR1_RXCFG(0U) |
FCIIC_SCFGR1_TXCFG(0U) |
FCIIC_SCFGR1_SAEN(0U) |
FCIIC_SCFGR1_GCEN(0U) |
FCIIC_SCFGR1_ACKSTALL(0U) |
FCIIC_SCFGR1_TXDSTALL(0U) |
FCIIC_SCFGR1_RXSTALL(0U) |
FCIIC_SCFGR1_ADRSTALL(0U);
u32TempScfgr2 = FCIIC_SCFGR2_FILTSDA(0U) |
FCIIC_SCFGR2_FILTSCL(0U) |
FCIIC_SCFGR2_DATAVD(0x09U) |
FCIIC_SCFGR2_CLKHOLD(1U);
u32TempSamr = FCIIC_SAMR_ADDR1(0U) |
FCIIC_SAMR_ADDR0(pInitCfg->u8SlaveAddr);
FCIIC_HWA_SetSDER(pFciic, u32TempSder);
FCIIC_HWA_SetSCFGR1(pFciic, u32TempScfgr1);
FCIIC_HWA_SetSCFGR2(pFciic, u32TempScfgr2);
FCIIC_HWA_SetSAMR(pFciic, u32TempSamr);
FCIIC_HWA_SetSCR(pFciic, u32TempScr);
return 0U;
}
/***************************************************
* FCIIC_DeInit_Slave
* @detail: Iic device master mode de-initial
*
* param in : pInitCfg, pFciic initial config parameters
* structure address
* param out: none
*
* return : 0 is ok, others are not ok
* ************************************************/
static uint8_t FCIIC_DeInit_Slave(uint8_t u8IicIndex)
{
uint32_t u32TempScr, u32TempSder;
FCIIC_Type *pFciic;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
u32TempScr = FCIIC_SCR_FILTEN(0U) |
FCIIC_SCR_RST(0U) |
FCIIC_SCR_SEN(0U); /* slave enable */
u32TempSder = FCIIC_SDER_AVDE(0U) |
FCIIC_SDER_RDDE(0U) | /* disable receive dma */
FCIIC_SDER_TDDE(0U); /* disable transmit dma */
FCIIC_HWA_SetSDER(pFciic, u32TempSder);
FCIIC_HWA_SetSCR(pFciic, u32TempScr);
return 0U;
}
/* ################################################################################## */
/* ################################ Global Functions ################################ */
/**
* \brief This Function is used to initial IIC instance
*
* \param u8IicIndex Iic Index, 0,1
* \param pInitCfg is the structure address of IIC initial configuration parameters, and it contains IIC instance
* \return 0 is ok, others are not ok
*/
uint8_t FCIIC_Init(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg)
{
/* master mode */
if (pInitCfg->bMasterMode != 0U)
{
FCIIC_Init_Master(u8IicIndex, pInitCfg);
#ifdef FCIIC_RX_ALL_POLLING
s_aFCIIC_IicMasterUsed[u8IicIndex] = 1U;
s_aFCIIC_IicSlaveUsed[u8IicIndex] = 0U;
#endif
}
else /* slave mode */
{
FCIIC_Init_Slave(u8IicIndex, pInitCfg);
#ifdef FCIIC_RX_ALL_POLLING
s_aFCIIC_IicMasterUsed[u8IicIndex] = 0U;
s_aFCIIC_IicSlaveUsed[u8IicIndex] = 1U;
#endif
}
#if (defined(__ICCARM__))
u8IicIndex = u8IicIndex;
#elif defined __GNUC__
(void)u8IicIndex;
#endif
return 0U;
}
/**
* \brief This Function is used to de-initial IIC instance
*
* \param u8IicIndex Iic Index, 0,1
* \param pInitCfg is the structure address of IIC initial configuration parameters, bMaster should be set
* \return 0 is ok, others are not ok
*/
uint8_t FCIIC_DeInit(uint8_t u8IicIndex, FCIIC_InitType *pInitCfg)
{
/* master mode */
if (pInitCfg->bMasterMode != 0U)
{
FCIIC_DeInit_Master(u8IicIndex);
#ifdef FCIIC_RX_ALL_POLLING
s_aFCIIC_IicMasterUsed[u8IicIndex] = 0U;
s_aFCIIC_IicSlaveUsed[u8IicIndex] = 0U;
#endif
}
else /* slave mode */
{
FCIIC_DeInit_Slave(u8IicIndex);
#ifdef FCIIC_RX_ALL_POLLING
s_aFCIIC_IicMasterUsed[u8IicIndex] = 0U;
s_aFCIIC_IicSlaveUsed[u8IicIndex] = 0U;
#endif
}
#if (defined(__ICCARM__))
u8IicIndex = u8IicIndex;
#elif defined __GNUC__
(void)u8IicIndex;
#endif
return 0U;
}
/**
* \brief This Function is used to configure IIC master interrupt
*
* \param u8IicIndex Iic Index, 0,1
* \param pIntCfg contains IIC instance and interrupt callback functions
* \return 0 is ok, others are not ok
*/
uint8_t FCIIC_Master_SetInterrupt(uint8_t u8IicIndex, FCIIC_InterruptType *pIntCfg)
{
FCIIC_Type *pFciic;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
if ((pIntCfg->bEnErrorInterrupt != 0U) || (pIntCfg->bEnRxInterrupt != 0U))
{
/* enable global interrupt for pFciic */
IntMgr_EnableInterrupt((IRQn_Type)((uint8_t)((uint8_t)FCIIC0_IRQn + u8IicIndex)));
/* IntMag_ReplaceHandler(FCIIC0_IRQn+u8IicIndex,u8IicIndex==0?FCIIC0_IRQHandler:FCIIC1_IRQHandler); */
}
if (pIntCfg->bEnErrorInterrupt != 0U)
{
FCIIC_Master_HWA_EnableErrorInterrupt(pFciic);
s_aFCIIC_ErrorNotifyTable[u8IicIndex] = pIntCfg->pErrorNotify;
}
if (pIntCfg->bEnRxInterrupt != 0U)
{
/* pFciic->MIER |= FCIIC_MIER_RDIE_MASK; */
FCIIC_Master_HWA_EnableReceiveInterrupt(pFciic);
s_aFCIIC_RxNotifyTable[u8IicIndex] = pIntCfg->pRxNotify;
}
return 0U;
}
/**
* \brief This Function is used to transmit data in master mode
*
* \param u8IicIndex Iic Index, 0,1
* \param pTxData contains IIC instance and buffer address
* \return 0 is ok, others are not ok
*/
uint8_t FCIIC_Master_Transmit(uint8_t u8IicIndex, FCIIC_TxDataType *pTxData)
{
uint8_t u8RetVal;
FCIIC_Type *pFciic;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
/* clear error flag */
/* CheckAndClear(pFciic); */
/* check tx data flag */
u8RetVal = FCIIC_Master_HWA_GetStatus(pFciic, FCIIC_MSR_TDF_STATUS);
/* pFciic->MSR |= FCIIC_MSR_FEF_MASK; */ /* clear fifo error error */
if (u8RetVal == 1U)
{
FCIIC_Master_HWA_Transmit(pFciic, pTxData->eCmd, pTxData->u8Data);
}
return (uint8_t)(1U >> u8RetVal);
}
/**
* \brief This Function is used to get master status
*
* \param u8IicIndex is IIC instance
* \param eStatus is status type enumeration
* \return 0 is ok, others are not ok
*/
uint8_t FCIIC_Master_GetStatus(uint8_t u8IicIndex, FCIIC_MasterStatusType eStatus)
{
FCIIC_Type *pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
return (uint8_t)(1U >> FCIIC_Master_HWA_GetStatus(pFciic, eStatus));
}
/**
* \brief This Function is used to receive data when polling (not used when rx interrupt enabled) in master mode
*
* \param u8IicIndex Iic Index, 0,1
* \param pRxData contains IIC instance
* \return 0 is ok, others are not ok
*/
uint8_t FCIIC_Master_Receive(uint8_t u8IicIndex, FCIIC_RxDataType *pRxData)
{
FCIIC_Type *pFciic;
uint8_t u8RetVal;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
/* CheckAndClear(pFciic); */
/* check receive flag */
u8RetVal = FCIIC_Master_HWA_GetStatus(pFciic, FCIIC_MSR_RDF_STATUS);
/* u8RetVal = (pFciic->MRDR & FCIIC_MRDR_RXEMPTY_MASK)>>FCIIC_MRDR_RXEMPTY_SHIFT; */
if (u8RetVal == 1U)
{
/* copy data */
pRxData->u8Data = FCIIC_Master_HWA_Receive(pFciic);
}
return (uint8_t)(1U >> u8RetVal);
}
/**
* \brief This Function is used to get master error value
*
* \param u8IicIndex Iic Index, 0,1
* \return error value
*/
uint32_t FCIIC_Master_GetError(uint8_t u8IicIndex)
{
FCIIC_Type *pFciic;
uint32_t u32RetVal;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
/* check receive flag */
u32RetVal = FCIIC_Master_HWA_GetErrorFlag(pFciic);
return u32RetVal;
}
/**
* \brief This Function is used to clear master error value
*
* \param u8IicIndex Iic Index, 0,1
*/
void FCIIC_Master_ClrError(uint8_t u8IicIndex)
{
FCIIC_Type *pFciic;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
/* clear receive flag */
FCIIC_Master_HWA_ClrErrorFlag(pFciic);
}
/**
* \brief This Function is used to configure IIC slave interrupt
*
* \param u8IicIndex Iic Index, 0,1
* \param pIntCfg contains IIC instance and interrupt callback functions
* \return 0 is ok, others are not ok
*/
uint8_t FCIIC_Slave_SetInterrupt(uint8_t u8IicIndex, FCIIC_InterruptType *pIntCfg)
{
FCIIC_Type *pFciic;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
if ((pIntCfg->bEnErrorInterrupt != 0U) || (pIntCfg->bEnRxInterrupt != 0U))
{
/* enable global interrupt for pFciic */
IntMgr_EnableInterrupt((IRQn_Type)((uint8_t)((uint8_t)FCIIC0_IRQn + u8IicIndex)));
/* IntMag_ReplaceHandler(FCIIC0_IRQn+u8IicIndex,u8IicIndex==0?FCIIC0_IRQHandler:FCIIC1_IRQHandler); */
}
if (pIntCfg->bEnErrorInterrupt != 0U)
{
FCIIC_Slave_HWA_EnableErrorInterrupt(pFciic);
s_aFCIIC_ErrorNotifyTable[u8IicIndex] = pIntCfg->pErrorNotify;
}
if (pIntCfg->bEnRxInterrupt != 0U)
{
FCIIC_Slave_HWA_EnableReceiveInterrupt(pFciic);
s_aFCIIC_RxNotifyTable[u8IicIndex] = pIntCfg->pRxNotify;
}
return 0U;
}
/**
* \brief This Function is used to transmit data in slave mode
*
* \param u8IicIndex Iic Index, 0,1
* \param pTxData contains IIC instance and buffer address
* \return 0 is ok, others are not ok
*/
uint8_t FCIIC_Slave_Transmit(uint8_t u8IicIndex, FCIIC_TxDataType *pTxData)
{
#ifdef FCIIC_TX_CHECK
uint8_t u8RetVal;
uint32_t u32TryTick;
uint32_t u32TryCount;
#endif
FCIIC_Type *pFciic;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
#ifdef FCIIC_TX_CHECK
/* u8RetVal = (pFciic->SSR & FCIIC_SSR_TDF_MASK)>> FCIIC_SSR_TDF_SHIFT; */
/* pFciic->SSR |= FCIIC_SSR_TREF_MASK; */ /* clear receive & transmit error error */
/* if(u8RetVal) */
{
#endif
FCIIC_Slave_HWA_Transmit(pFciic, pTxData->u8Data);
#ifdef FCIIC_TX_CHECK
/* after transmit completed, close TE */
/* u8RetVal = 0; */
/* u32TryCount = 0; */
/* while(u8RetVal==0 && u32TryCount++<100) */
/* { */
/* u8RetVal = (pFciic->SSR & FCIIC_SSR_TDF_MASK)>> FCIIC_SSR_TDF_SHIFT; */
/* u32TryTick = 0; */
/* while(u32TryTick++<100){} */
/* } */
}
#endif
return 0U;
}
/**
* \brief This Function is used to receive data when polling (not used when rx interrupt enabled) in slave mode
*
* \param u8IicIndex Iic Index, 0,1
* \param pRxData contains IIC instance and buffer address
* \return 0 is ok, others are not ok
*/
uint8_t FCIIC_Slave_Receive(uint8_t u8IicIndex, FCIIC_RxDataType *pRxData)
{
FCIIC_Type *pFciic;
uint8_t u8RetVal;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
/* check slave receive flag */
u8RetVal = FCIIC_Slave_HWA_GetStatus(pFciic, FCIIC_SSR_RDF_STATUS);
/* u8RetVal = (pFciic->MRDR & FCIIC_MRDR_RXEMPTY_MASK)>>FCIIC_MRDR_RXEMPTY_SHIFT; */
if (u8RetVal != 0U)
{
/* get received data */
pRxData->u8Data = FCIIC_Slave_HWA_Receive(pFciic);
}
return (uint8_t)(1U >> u8RetVal);
}
/**
* \brief This Function is used to get slave error value
*
* \param u8IicIndex Iic Index, 0,1
* \return error value
*/
uint32_t FCIIC_Slave_GetError(uint8_t u8IicIndex)
{
FCIIC_Type *pFciic;
uint32_t u32RetVal;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
/* check receive flag */
u32RetVal = FCIIC_Slave_HWA_GetErrorFlag(pFciic);
return u32RetVal;
}
/**
* \brief This Function is used to clear slave error value
*
* \param u8IicIndex Iic Index, 0,1
*/
void FCIIC_Slave_ClrError(uint8_t u8IicIndex)
{
FCIIC_Type *pFciic;
pFciic = (FCIIC_Type *)s_aFCIIC_InstanceTable[u8IicIndex];
/* clear receive flag */
FCIIC_Slave_HWA_ClrErrorFlag(pFciic);
}
/* ################################################################################## */
/* ############################## Interrupt Services ################################ */
void FCIIC0_IRQHandler(void)
{
FCIIC_LL_MasterIRQnHandler(0U);
FCIIC_LL_SlaveIRQnHandler(0U);
}
void FCIIC1_IRQHandler(void)
{
FCIIC_LL_MasterIRQnHandler(1U);
FCIIC_LL_SlaveIRQnHandler(1U);
}