📄 i2cclass.cpp
字号:
}
i2cr= INREG16(&pI2CReg->I2CR);
if (CSP_BITFEXT(i2cr, I2C_I2CR_IIEN)==1)
{
// the interface is preempted by master mode
goto __loop;
}
}
CSP_BITFCLR(i2sr, I2C_I2SR_IIF);
OUTREG16(&pI2CReg->I2SR, i2sr);
if (CSP_BITFEXT(i2sr, I2C_I2SR_RXAK)!=0)
{
goto end_transmit;
}
}
}
end_transmit:
i2sr= INREG16(&pI2CReg->I2SR);
CSP_BITFCLR(i2sr, I2C_I2SR_IAL);
CSP_BITFCLR(i2sr, I2C_I2SR_IIF);
OUTREG16(&pI2CReg->I2SR, i2sr);
i2cr= INREG16(&pI2CReg->I2CR);
CSP_BITFCLR(i2cr, I2C_I2CR_MTX);
i2cr |= CSP_BITFVAL(I2C_I2CR_IIEN, 1);
i2cr |= CSP_BITFVAL(I2C_I2CR_TXAK, 1);
OUTREG16(&pI2CReg->I2CR, i2cr);
OUTREG16(&pI2CReg->I2SR, i2sr);
INREG16(&pI2CReg->I2DR);
}
else
{
// I2C slave is in receive mode
if(pSBuf->iBufSize<=1)
{
CSP_BITFCLR(i2cr, I2C_I2CR_MTX);
i2cr|=CSP_BITFVAL(I2C_I2CR_TXAK, 1);
OUTREG16(&pI2CReg->I2CR, i2cr);
INREG16(&pI2CReg->I2DR);
iIdleCount=I2C_TRANSMIT_WAIT;
i2sr= INREG16(&pI2CReg->I2SR);
while (CSP_BITFEXT(i2sr, I2C_I2SR_IIF)!=1)
{
--iIdleCount;
if( iIdleCount<= (I2C_TRANSMIT_WAIT*8/9)
&& (CSP_BITFEXT(i2sr, I2C_I2SR_ICF)!=0) )
{
goto end_receive;
}
if( iIdleCount<=0 )
{
goto end_receive;
}
i2sr= INREG16(&pI2CReg->I2SR);
if (CSP_BITFEXT(i2sr, I2C_I2SR_IAL)==1)
{
goto end_receive;
}
if (CSP_BITFEXT(i2sr, I2C_I2SR_IBB)==0)
{
goto end_receive;
}
if (CSP_BITFEXT(i2sr, I2C_I2SR_IAAS)==1)
{
goto iaas_slave;
}
i2cr= INREG16(&pI2CReg->I2CR);
if (CSP_BITFEXT(i2cr, I2C_I2CR_IIEN)==1)
{
// the interface is preempted by master mode
goto __loop;
}
}
pSBuf->byBuf[0]=(BYTE)INREG16(&pI2CReg->I2DR);
}
else
{
CSP_BITFCLR(i2cr, I2C_I2CR_MTX);
CSP_BITFCLR(i2cr, I2C_I2CR_TXAK);
OUTREG16(&pI2CReg->I2CR, i2cr);
INREG16(&pI2CReg->I2DR);
for (i=0; i<pSBuf->iBufSize; ++i)
{
if (i>=pSBuf->iBufSize-1)
{
i2cr|=CSP_BITFVAL(I2C_I2CR_TXAK, 1);
OUTREG16(&pI2CReg->I2CR, i2cr);
}
iIdleCount=I2C_TRANSMIT_WAIT;
i2sr= INREG16(&pI2CReg->I2SR);
while (CSP_BITFEXT(i2sr, I2C_I2SR_IIF)!=1)
{
--iIdleCount;
if( iIdleCount<= (I2C_TRANSMIT_WAIT*8/9)
&& (CSP_BITFEXT(i2sr, I2C_I2SR_ICF)!=0) )
{
goto end_receive;
}
if( iIdleCount<=0 )
{
goto end_receive;
}
i2sr= INREG16(&pI2CReg->I2SR);
if (CSP_BITFEXT(i2sr, I2C_I2SR_IAL)==1)
{
goto end_receive;
}
if (CSP_BITFEXT(i2sr, I2C_I2SR_IBB)==0)
{
goto end_receive;
}
if (CSP_BITFEXT(i2sr, I2C_I2SR_IAAS)==1)
{
goto iaas_slave;
}
i2cr= INREG16(&pI2CReg->I2CR);
if (CSP_BITFEXT(i2cr, I2C_I2CR_IIEN)==1)
{
// the interface is preempted by master mode
goto __loop;
}
}
pSBuf->byBuf[i]= (BYTE)INREG16(&pI2CReg->I2DR);
CSP_BITFCLR(i2sr, I2C_I2SR_IIF);
OUTREG16(&pI2CReg->I2SR, i2sr);
if (CSP_BITFEXT(i2sr, I2C_I2SR_RXAK)!=0)
{
goto end_receive;
}
if (!bSlaveEventNotified)
{
SetEvent(m_hI2CUpdateSlaveEvent);
bSlaveEventNotified = TRUE;
}
}
}
end_receive:
i2sr= INREG16(&pI2CReg->I2SR);
CSP_BITFCLR(i2sr, I2C_I2SR_IAL);
CSP_BITFCLR(i2sr, I2C_I2SR_IIF);
OUTREG16(&pI2CReg->I2SR, i2sr);
i2cr= INREG16(&pI2CReg->I2CR);
i2cr |= CSP_BITFVAL(I2C_I2CR_IIEN, 1);
i2cr |= CSP_BITFVAL(I2C_I2CR_TXAK, 1);
OUTREG16(&pI2CReg->I2CR, i2cr);
if (!bSlaveEventNotified)
{
SetEvent(m_hI2CUpdateSlaveEvent);
bSlaveEventNotified = TRUE;
}
}
}
else
{
if (bDispatchEvent){
SetEvent(m_hI2CIntrEvent);
}
else
{
if (EXTREG16(&pI2CReg->I2CR, CSP_BITFMASK(I2C_I2CR_IEN),
I2C_I2CR_IEN_LSH)== I2C_I2CR_IEN_ENABLE)
{
OUTREG16(&pI2CReg->I2CR, 0);
}
InterruptDone(dwSysIntr);
DEBUGMSG (ZONE_FUNCTION, (_T("interrupt event discard.\r\n")));
}
}
}
else
{
DEBUGMSG (ZONE_ERROR, (TEXT("%s: Time out\r\n"), __WFUNCTION__));
}
}
// Should only ever get here with bTerminateISTThread == TRUE.
return;
}
//-----------------------------------------------------------------------------
//
// Function: RealMode
//
// This method return the Master/Slave settings in register level.
//
// Parameters:
//
// Returns:
// I2C_MASTER_MODE: i2c circult currently work in MASTER mode
// I2C_SLAVE_MODE: i2c circult currently work in SLAVE mode
//
//-----------------------------------------------------------------------------
BYTE I2CClass::RealMode(void)
{
UINT16 i2cr;
i2cr = INREG16(&pI2CReg->I2CR);
if ( CSP_BITFEXT(i2cr, I2C_I2CR_MSTA)==I2C_I2CR_MSTA_SLAVE)
{
return I2C_SLAVE_MODE;
}
return I2C_MASTER_MODE;
}
//-----------------------------------------------------------------------------
//
// Function: EnableSlave
//
// This method enable i2c slave from clock gating.
//
// Parameters:
//
// Returns:
// TRUE: enabled SLAVE mode
// FALSE: enable fail
//
//-----------------------------------------------------------------------------
BOOL I2CClass::EnableSlave(void)
{
UINT16 i2cr;
BOOL retVal = FALSE;
if (TryEnterCriticalSection(&gcsI2CBusLock)==FALSE)
{
return FALSE;
}
// Enabling I2C Clock
if (!bSlaveInUse)
{
if (!BSPI2CEnableClock(m_iModuleIndex, TRUE))
{
BSPI2CEnableClock(m_iModuleIndex, FALSE);
goto __exit;
}
}
i2cr = INREG16(&pI2CReg->I2CR);
if ( CSP_BITFEXT(i2cr, I2C_I2CR_MSTA)==I2C_I2CR_MSTA_MASTER)
{
// Master conversation is in progress
goto __exit;
}
// Reset I2CR
OUTREG16(&pI2CReg->I2CR, 0);
// Configure data sampling rate, and slave address
OUTREG16(&pI2CReg->IFDR, CSP_BITFVAL(I2C_IFDR_IC, wLastClkRate));
OUTREG16(&pI2CReg->IADR, CSP_BITFVAL(I2C_IADR_ADR, byLastSelfAddr));
// Init I2CR
i2cr = CSP_BITFVAL(I2C_I2CR_IEN, 1);
OUTREG16(&pI2CReg->I2CR, i2cr);
i2cr = CSP_BITFVAL(I2C_I2CR_IEN, 1)|CSP_BITFVAL(I2C_I2CR_IIEN, 1);
OUTREG16(&pI2CReg->I2CR, i2cr);
OUTREG16(&pI2CReg->I2SR, 0);
DEBUGMSG(ZONE_FUNCTION, (TEXT("I2CClass::EnableSlave(): Re init I2CR \r\n")));
// inform the port setting is slave
bSlaveInUse = TRUE;
retVal = TRUE;
__exit:
LeaveCriticalSection(&gcsI2CBusLock);
return retVal;
}
//-----------------------------------------------------------------------------
//
// Function: DisableSlave
//
// This method disable i2c slave and gate its input clock.
//
// Parameters:
//
// Returns:
// TRUE: disabled SLAVE mode
// FALSE: disable fail
//
//-----------------------------------------------------------------------------
BOOL I2CClass::DisableSlave(void)
{
UINT16 i2cr;
BOOL retVal = FALSE;
if (TryEnterCriticalSection(&gcsI2CBusLock)==FALSE)
{
return FALSE;
}
i2cr = INREG16(&pI2CReg->I2CR);
if ( CSP_BITFEXT(i2cr, I2C_I2CR_MSTA)==I2C_I2CR_MSTA_MASTER)
{
// Master conversation is in progress
goto __exit;
}
if (!bSlaveInUse)
{
// Slave is already disabled
retVal = TRUE;
goto __exit;
}
// Reset I2CR
OUTREG16(&pI2CReg->I2CR, 0);
OUTREG16(&pI2CReg->I2SR, 0);
DEBUGMSG(ZONE_FUNCTION, (TEXT("I2CClass::DisableSlave(): I2CR \r\n")));
// disable i2c module clock
BSPI2CEnableClock(m_iModuleIndex, FALSE);
// inform the port setting is no slave
bSlaveInUse = FALSE;
retVal = TRUE;
__exit:
LeaveCriticalSection(&gcsI2CBusLock);
return retVal;
}
//-----------------------------------------------------------------------------
//
// Function: SetSlaveText
//
// This method set slave text in slave interface buffer.
//
// Parameters:
//
// Returns:
// TRUE: success
// FALSE: fail
//
//-----------------------------------------------------------------------------
BOOL I2CClass::SetSlaveText(PBYTE pBufIn, DWORD dwLen)
{
if ((INT)dwLen <=0 || (INT)dwLen >pSBuf->iBufSize)
{
return FALSE;
}
if (TryEnterCriticalSection(&gcsI2CSlaveLock)==FALSE)
{
return FALSE;
}
memcpy(pSBuf->byBuf, pBufIn, dwLen);
bSlaveEventNotified = FALSE;
LeaveCriticalSection(&gcsI2CSlaveLock);
return TRUE;
}
//-------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -