#include <I2CHwCtxt.h>
#include <oal_i2cemul.h>
#include <stdlib.h>
#include <drvmsg.h>
//===== DEBUGGING MACRO DEFINITION =============================================================================
//#define TEST_MODE
#define TEST_IST FALSE
//==============================================================================================================
//===== MACRRO DEFINITION ======================================================================================
//#define SDA_SETUP_TIME
#define DIVIDE_BY_16_SEL 0
#define DIVIDE_BY_512_SEL 1
#define ARBITRATION_FLAS (1<<3)
#define MATCHED_SADDR_FLAG (1<<2)
#define ZERO_SADDR_FLAG (1<<1)
#define ACK_NOT_RCVD_FLAG (1<<0)
#define PRIO (dwFIFOIdx-1)
#define CURR (dwFIFOIdx)
#define NEXT (dwFIFOIdx+1)
#define NEXT_NEXT (dwFIFOIdx+2)
#define rIICCON pI2CReg->IICCON
#define rIICSTAT pI2CReg->IICSTAT
#define rIICDS pI2CReg->IICDS
#define rIICLC pI2CReg->IICLC
#define M_IDLE 0x00 // Disable Rx/Tx
#define M_ACTIVE 0x10 // Enable Rx/Tx
#define MTX_START 0xF0 // Master Tx Start
#define MTX_STOP 0xD0 // Master Tx Stop
#define MRX_START 0xB0 // Master Rx Start
#define MRX_STOP 0x90 // Master Rx Stop
#define EDID_SEGMENT_ADDR (0x60)
//==============================================================================================================
//===== GLOBAL VARIABLE DECLARTION =============================================================================
//==============================================================================================================
//===== LOCAL FUNCTION DECLARTION ==============================================================================
VOID CallI2CInterruptThread(I2CHWContext *pHWContext);
//==============================================================================================================
//===== IST TIME OUT ==============================================================================
int IST_TIMEOUT = 500; // suryeon.lim 20090407
//==============================================================================================================
//===== EXTERN FUNCTION DECLARTION =============================================================================
//==============================================================================================================
I2CObject::I2CObject()
{
DBGMSG(IIC_FUNC, (L"[I2C:F] +++ I2CObject::I2CObject()\r\n"));
Init();
InitializeCriticalSection(&I2COB_CS);
DBGMSG(IIC_FUNC, (L"[I2C:F] --- I2CObject::I2CObject()\r\n"));
}
I2CObject::~I2CObject()
{
DBGMSG(IIC_FUNC, (L"[I2C:F] +++ I2CObject::~I2CObject()\r\n"));
do
{
DeleteCriticalSection(&I2COB_CS);
} while(FALSE);
DBGMSG(IIC_FUNC, (L"[I2C:F] --- I2CObject::~I2CObject()\r\n"));
}
VOID
I2CObject::Init(VOID)
{
wSlaveAddr = DEFAULT_SLAVE_ADDR;
Mode = I2CMODE_END;
dwFIFOIdxCnt = 0;
pTxBuffer = NULL;
dwTxCount = 0;
pRxBuffer = NULL;
dwRxCount = 0;
ClrStateFIFO();
}
DWORD
I2CObject::Init(BOOL bEmulation, WORD wSlaveAddr, DWORD dwTempClockSpeed)
{
Init();
this->bEmulation = bEmulation;
SetSlaveAddr(wSlaveAddr);
SetClockSpeed(dwTempClockSpeed);
bInitialized = TRUE;
return dwClockSpeed;
}
VOID
I2CObject::SetClockSpeed(DWORD dwTempClockSpeed)
{
DWORD dwTarget, dwTemp1, dwTemp2, dwTemp3;
DBGMSG(IIC_FUNC, (L"[I2C_HW:F] +++ I2CObject::SetClockSpeed()\r\n"));
if(bEmulation)
{
dwClockSpeed = dwTempClockSpeed;
}
else
{
if(dwTempClockSpeed >= ((SXXXXXX_PCLK/1000)/256))
{
dwClockPSSelBit = DIVIDE_BY_16_SEL;
dwTarget = (SXXXXXX_PCLK/1000)/16;
DBGMSG(IIC_INFO, (L"[I2C_HW:I] PRESCALE : DIVIDE_BY_16_SEL\r\n"));
}
else
{
dwClockPSSelBit = DIVIDE_BY_512_SEL;
dwTarget = (SXXXXXX_PCLK/1000)/512;
DBGMSG(IIC_INFO, (L"[I2C_HW:I] PRESCALE : DIVIDE_BY_512_SEL\r\n"));
}
dwTemp1 = 0xFFFFFFFF;
dwClockSpeed = 0;
dwClockValue = 0;
for(DWORD i=0; i<16; i++)
{
dwTemp3 = dwTarget/(i+1);
dwTemp2 = abs(dwTempClockSpeed - dwTemp3);
if( (dwTemp1 > dwTemp2) && (dwTemp3 <= dwTempClockSpeed) )
{
dwTemp1 = dwTemp2;
dwClockValue = i;
dwClockSpeed = dwTemp3;
DBGMSG(IIC_INFO, (L"[I2C_HW:I] *SCALE[%d] : %dKhz\r\n", i, dwTemp3));
}
else
DBGMSG(IIC_INFO, (L"[I2C_HW:I] SCALE[%d] : %dKhz\r\n", i, dwTemp3));
}
}
DBGMSG(IIC_FUNC, (L"[I2C_HW:F] --- I2CObject::SetClockSpeed()\r\n"));
}
BOOL
I2CObject::SetSlaveAddr(WORD wAddr)
{
DBGMSG(IIC_FUNC, (L"[I2C:F] +++ I2CObject::SetSlaveAddr()\r\n"));
if((wAddr & GENERAL_ADDR_MASK) == GENERAL_ADDR)
{
ERRMSG((L"[I2C:E] UNSUPPORTABLE GERNERAL_ADDR\r\n"));
return FALSE;
}
else if((wAddr & START_BYTE_MASK) == START_BYTE)
{
ERRMSG((L"[I2C:E] UNSUPPORTABLE START_BYTE\r\n"));
return FALSE;
}
else if((wAddr & CBUS_ADDR_MASK) == CBUS_ADDR)
{
ERRMSG((L"[I2C:E] UNSUPPORTABLE CBUS_ADDR\r\n"));
return FALSE;
}
else if((wAddr & FOR_OTHER_BUS_MASK) == FOR_OTHER_BUS)
{
ERRMSG((L"[I2C:E] UNSUPPORTABLE FOR_OTHER_BUS\r\n"));
return FALSE;
}
else if((wAddr & FOR_FUTURE1_MASK) == FOR_FUTURE1)
{
ERRMSG((L"[I2C:E] UNSUPPORTABLE FOR_FUTURE1\r\n"));
return FALSE;
}
else if((wAddr & HS_MODE_MASK) == HS_MODE)
{
ERRMSG((L"[I2C:E] UNSUPPORTABLE HS_MODE\r\n"));
return FALSE;
}
else if((wAddr & FOR_FUTURE2_MASK) == FOR_FUTURE2)
{
ERRMSG((L"[I2C:E] UNSUPPORTABLE FOR_FUTURE2\r\n"));
return FALSE;
}
else if((wAddr & TEN_BIT_ADDR_MASK) == TEN_BIT_ADDR)
{
ERRMSG((L"[I2C:E] UNSUPPORTABLE TEN_BIT_ADDR\r\n"));
return FALSE;
}
else
{
wSlaveAddr = (wAddr & 0xFE);
DBGMSG(IIC_INFO, (L"[I2C:I] Slave Address : 0x%X \r\n", wSlaveAddr));
return TRUE;
}
DBGMSG(IIC_FUNC, (L"[I2C:F] --- I2CObject::SetSlaveAddr()\r\n"));
}
BOOL
I2CObject::IsValidFIFOIdxCnt(VOID)
{
if(dwFIFOIdxCnt >= I2C_STATE_MAX) return FALSE;
return TRUE;
}
VOID
I2CObject::ClrStateFIFO(VOID)
{
dwFIFOIdxCnt = 0;
for(DWORD i=0; i<I2C_STATE_MAX; ++i)
{
StateFIFO[i].State = I2CSTATE_UNDEFINED;
StateFIFO[i].pbtData = NULL;
StateFIFO[i].btData = 0;
StateFIFO[i].dwTime = 0;
}
pTxBuffer = NULL;
dwTxCount = 0;
pRxBuffer = NULL;
dwRxCount = 0;
}
I2CObject&
I2CObject::Begin(VOID)
{
DBGMSG(IIC_FUNC, (L"[I2C:F] +++I2CObject::Begin(Slave Addr : 0x%X)\r\n", wSlaveAddr));
if(!IsValidFIFOIdxCnt() || !bInitialized)
{
ERRMSG((L"[I2C:E] FIFO index count is INVALID or Initializing is INVALID\r\n"));
bSuccess = FALSE;
StateFIFO[dwFIFOIdxCnt].State = I2CSTATE_BEGIN | I2CERR_INVALID_INIT;
return *this;
}
StateFIFO[dwFIFOIdxCnt].State = I2CSTATE_BEGIN;
dwFIFOIdxCnt++;
bSuccess = TRUE;
DBGMSG(IIC_FUNC, (L"[I2C:F] ---I2CHWContext::Begin()\r\n"));
return *this;
}
I2CObject&
I2CObject::SetStartCustom(DWORD dwMode)
{
if(!bSuccess || !IsValidFIFOIdxCnt())
{
ERRMSG((L"[I2C_HW:E] Some error is occured before SetStart state\r\n"));
bSuccess = FALSE;
return *this;
}
if((dwMode != I2CMODE_MASTER_READ) && (dwMode != I2CMODE_MASTER_WRITE))
{
ERRMSG((L"[I2C_HW:E] The mode should be I2CMODE_MASTER_READ or I2CMODE_MASTER_WRITE\r\n"));
bSuccess = FALSE;
return *this;
}
StateFIFO[dwFIFOIdxCnt].State = I2CSTATE_START_CUSTOM;
StateFIFO[dwFIFOIdxCnt].btData = (BYTE)dwMode;
dwFIFOIdxCnt++;
return *this;
}
I2CObject&
I2CObject::SetStart(DWORD dwMode)
{
if(!bSuccess || !IsValidFIFOIdxCnt())
{
ERRMSG((L"[I2C_HW:E] Some error is occured before SetStart state\r\n"));
bSuccess = FALSE;
return *this;
}
if((dwMode != I2CMODE_MASTER_READ) && (dwMode != I2CMODE_MASTER_WRITE))
{
ERRMSG((L"[I2C_HW:E] The mode should be I2CMODE_MASTER_READ or I2CMODE_MASTER_WRITE\r\n"));
bSucce
评论0