818 lines
23 KiB
C
818 lines
23 KiB
C
/**
|
||
* @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);
|
||
}
|
||
|
||
|