RabbitECUTeensyMCUXpresso/source/Peripherals/IICHA.c

203 lines
5.3 KiB
C

/******************************************************************************/
/* Copyright (c) 2016 MD Automotive Controls. Original Work. */
/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */
/******************************************************************************/
/* CONTEXT:KERNEL */
/* PACKAGE TITLE: XXX */
/* DESCRIPTION: XXX */
/* FILE NAME: XXX.c */
/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */
/* */
/******************************************************************************/
#include "IICHA.h"
const REGSET_tstReg8Val IICHA_rastPIMReg8ValIIC0[] = IICHA_nReg8SetIIC0;
const REGSET_tstReg8Val IICHA_rastPIMReg8ValIIC1[] = IICHA_nReg8SetIIC1;
const IICHA_tstDivisorMap IICHA_rastDivisorMap[] = IICHA_nDivisorMap;
IOAPI_tstTransferCB* IICHA_pstTransferCB;
uint32 IICHA_u32BytesToTransfer;
void* IICHA_pvData;
IOAPI_tpfTransferCB IICHA_pfCB;
tstI2CModule* IICHA_pstIIC;
uint32 IIC_u32PortClockRequested;
static sint32 IICHA_u32GetIICIndex(IOAPI_tenEHIOResource);
void IICHA_vStart(puint32 const u32Stat)
{
IICHA_pfCB = NULL;
IICHA_pstIIC = NULL;
IICHA_u32BytesToTransfer = 0;
OS_xModuleStartOK(*u32Stat);
}
void IICHA_vRun(puint32 const pu32Stat)
{
}
void IICHA_vTerminate(puint32 const pu32Stat)
{
}
SYSAPI_tenSVCResult IICHA_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB)
{
SYSAPI_tenSVCResult enSVCResult = SYSAPI_enResourceAlreadyAllocated;
sint32 i32IDX = IICHA_u32GetIICIndex(enEHIOResource);
if ((-1 != i32IDX) && (TRUE == DLL_boInitDLLChannel(enEHIOResource, pstPortConfigCB)))
switch (enEHIOResource)
{
#ifdef BUILD_MK60
uint32 u32Mul;
uint32 u32DivCalc;
uint32 u32Div;
uint32 u32DivMapIDX;
tstI2CModule* pstIIC;
IRQn_Type enIRQType;
REGSET_tstReg32Val IIC_astIICReg32Val[3];
case EH_VIO_IIC1:
{
IIC_xRequestPortClock(SIM_SCGC4_IIC0_MASK);
IIC_astIICReg32Val[0].reg = (vpuint32)(PORTD_BASE + offsetof(PORT_Type, PCR[8]));
IIC_astIICReg32Val[0].val = (uint32)(PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK);
IIC_astIICReg32Val[0].writeMode = REGSET_enOverwrite;
IIC_astIICReg32Val[1].reg = (vpuint32)(PORTD_BASE + offsetof(PORT_Type, PCR[9]));
IIC_astIICReg32Val[1].val = (uint32)(PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK);
IIC_astIICReg32Val[1].writeMode = REGSET_enOverwrite;
IIC_astIICReg32Val[2].reg = NULL;
REGSET_vInitReg32(&IIC_astIICReg32Val[0]);
enSVCResult = SYSAPI_enBaudRateUnavailable;
pstIIC = I2C0;
IIC_xRequestPortClock(SIM_SCGC4_IIC0_MASK);
u32Mul = pstPortConfigCB->u32BaudRateHz / (SYS_FREQ_BUS / IIC_rastDivisorMap[0].u32SCLDivider);
u32Mul = (4 < u32Mul) ? 4 : u32Mul;
switch (u32Mul)
{
case 0: u32Mul = 1; break;
case 3: u32Mul = 2; break;
default: u32Mul = 4; break;
}
u32DivCalc = SYS_FREQ_BUS / (u32Mul * pstPortConfigCB->u32BaudRateHz);
if (IIC_rastDivisorMap[63].u32SCLDivider < u32DivCalc) break;
enSVCResult = SYSAPI_enOK;
IIC_xCalcDivisor;
enIRQType = I2C0_IRQn;
break;
}
case EH_VIO_IIC2:
{
IIC_xRequestPortClock(SIM_SCGC4_IIC1_MASK);
break;
}
#endif //BUILD_MK60
default:
{
break;
}
}
if (SYSAPI_enOK == enSVCResult)
{
#ifdef BUILD_MK60
pstIIC->F = (I2C_F_MULT(u32Mul) | I2C_F_ICR(u32Div));
pstIIC->C1 |= I2C_C1_IICEN_MASK;
IRQ_vEnableIRQ(enIRQType);
#endif //BUILD_MK60
}
return enSVCResult;
}
void IICHA_vInitTransfer(IOAPI_tstTransferCB* pstTransferCB)
{
IICHA_pstTransferCB = pstTransferCB;
switch (pstTransferCB->enEHIOResource)
{
#ifdef BUILD_MK60
case EH_VIO_IIC1:
{
IICHA_pstIIC = I2C0;
IICHA_u32BytesToTransfer = pstTransferCB->u32ByteCount - 1;
IICHA_pfCB = pstTransferCB->pfCB;
IICHA_pvData = pstTransferCB->pvData;
IICHA_pstIIC->C1 |= (I2C_C1_TX_MASK | I2C_C1_IICIE_MASK | I2C_C1_MST_MASK);
IICHA_pstIIC->D = *(uint8*)IIC_pvData;
IICHA_pvData = (void*)((uint32)IIC_pvData + 1);
}
#endif //BUILD_MK60
default:
{
break;
}
}
}
void IICHA_vInterrupt(IOAPI_tenEHIOResource enEHIOResource)
{
if (NULL != IICHA_pstIIC)
{
#ifdef BUILD_MK60
IOAPI_tenPortMode enMode;
IICHA_pstIIC->S |= I2C_S_IICIF_MASK;
if (0 < IICHA_u32BytesToTransfer)
{
IICHA_pstIIC->D = *(uint8*)IIC_pvData;
IICHA_pvData = (void*)((uint32)IIC_pvData + 1);
IICHA_u32BytesToTransfer -= 1;
}
else
{
IICHA_pstIIC->C1 &= ~(I2C_C1_IICIE_MASK | I2C_C1_MST_MASK);
enMode = DLL_enGetChannelMode(enEHIOResource);
if (IOAPI_enPortSerialTransfer == enMode)
{
SRLTFR_vNotifyCB(EH_VIO_IIC1);
}
else if (IOAPI_enPortComms == enMode)
{
//DLL_vFrameRXCB(enEHIOResource, &CAN_stRXDLLData);
}
}
#endif //BUILD_MK60
}
}
static sint32 IICHA_u32GetIICIndex(IOAPI_tenEHIOResource enEHIOResource)
{
sint32 i32IDX = -1;
if ((EH_VIO_IIC1 <= enEHIOResource) && (EH_VIO_IIC2 >= enEHIOResource))
{
i32IDX = enEHIOResource - EH_VIO_IIC1;
}
return i32IDX;
}