📄 i2c_io.cpp
字号:
// [in] Pointer to the buffer containing data to transfer to the
// device.
// dwLenIn
// [in] Number of bytes of data in the buffer specified for pBufIn.
//
// pBufOut
// [out] Pointer to the buffer used to transfer the output data
// from the device.
// dwLenOut
// [in] Maximum number of bytes in the buffer specified by pBufOut.
//
// pdwActualOut
// [out] Pointer to the DWORD buffer that this function uses to
// return the actual number of bytes received from the device.
//
// Returns:
// The new data pointer for the device indicates success. A value of -1
// indicates failure.
//
//-----------------------------------------------------------------------------
BOOL I2C_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
BOOL bRet = FALSE;
// Remove-W4: Warning C4100 workaround
UNREFERENCED_PARAMETER(pdwActualOut);
// hOpenContext is a pointer to I2CClass instance!
I2CClass* pI2C = (I2CClass*) hOpenContext;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl: +hOpenContext=0x%x\r\n"),hOpenContext));
if (pI2C != NULL)
{
switch (dwCode)
{
case I2C_IOCTL_SET_SLAVE_MODE:
{
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:SET_SLAVE_MODE +\r\n")));
pI2C->SetMode(I2C_SLAVE_MODE);
bRet = TRUE;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:SET_SLAVE_MODE -\r\n")));
break;
}
case I2C_IOCTL_SET_MASTER_MODE:
{
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:SET_MASTER_MODE +\r\n")));
pI2C->SetMode(I2C_MASTER_MODE);
bRet = TRUE;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:SET_MASTER_MODE +\r\n")));
break;
}
case I2C_IOCTL_IS_MASTER:
{
if (dwLenOut != sizeof(BOOL))
return FALSE;
if( (NULL == pBufOut) )
{
return FALSE;
}
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:IS_MASTER +\r\n")));
PBOOL pbIsMaster = (PBOOL) pBufOut;
if (pI2C->GetMode() == I2C_MASTER_MODE)
*pbIsMaster = TRUE;
else
*pbIsMaster = FALSE;
bRet = TRUE;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:IS_MASTER - Val=0x%x\r\n"), *pbIsMaster));
break;
}
case I2C_IOCTL_IS_SLAVE:
{
if (dwLenOut != sizeof(BOOL))
return FALSE;
if( (NULL == pBufOut) )
{
return FALSE;
}
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:IS_SLAVE +\r\n")));
PBOOL pbIsSlave = (PBOOL) pBufOut;
if (pI2C->GetMode() == I2C_SLAVE_MODE)
*pbIsSlave = TRUE;
else
*pbIsSlave = FALSE;
bRet = TRUE;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:IS_SLAVE - Val=0x%x\r\n"), *pbIsSlave));
break;
}
case I2C_IOCTL_GET_CLOCK_RATE:
{
if (dwLenOut != sizeof(WORD))
return FALSE;
if( (NULL == pBufOut) )
{
return FALSE;
}
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:GET_CLOCK_RATE +\r\n")));
PWORD pwClkRate = (PWORD) pBufOut;
*pwClkRate = pI2C->GetClockRateDivider();
bRet = TRUE;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:GET_CLOCK_RATE - Val=0x%x\r\n"), *pwClkRate));
break;
}
case I2C_IOCTL_SET_CLOCK_RATE:
{
if (dwLenIn != sizeof(WORD))
return FALSE;
if( (NULL == pBufIn) )
{
return FALSE;
}
PWORD pwClkRate = (PWORD) pBufIn;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:SET_CLOCK_RATE + ValIn=0x%x\r\n"), *pwClkRate));
pI2C->SetClockRateDivider(*pwClkRate);
bRet = TRUE;
break;
}
case I2C_IOCTL_SET_FREQUENCY:
{
if (dwLenIn != sizeof(DWORD))
return FALSE;
if( (NULL == pBufIn) )
{
return FALSE;
}
PDWORD pdwFrequency = (PDWORD) pBufIn;
DWORD dwFreq = *pdwFrequency;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:SET_FREQUENCY + ValIn=0x%x\r\n"), dwFreq));
if (*pdwFrequency > I2C_MAX_FREQUENCY)
{
RETAILMSG (1, (TEXT("I2C_IOControl: I2C frequency may not exceed %d...setting to %d\r\n"), I2C_MAX_FREQUENCY, I2C_MAX_FREQUENCY));
dwFreq = I2C_MAX_FREQUENCY;
bRet = FALSE;
}
WORD wClkRate = BSPCalculateClkRateDiv(dwFreq);
pI2C->SetClockRateDivider(wClkRate);
bRet = TRUE;
break;
}
case I2C_IOCTL_SET_SELF_ADDR:
{
if (dwLenIn != sizeof(BYTE))
return FALSE;
if( (NULL == pBufIn) )
{
return FALSE;
}
PBYTE pbySelfAddr = (PBYTE) pBufIn;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:SET_SELF_ADDR + ValIn=0x%x\r\n"), *pbySelfAddr));
pI2C->SetSelfAddress(*pbySelfAddr);
bRet = TRUE;
break;
}
case I2C_IOCTL_GET_SELF_ADDR:
{
if (dwLenOut != sizeof(BYTE))
return FALSE;
if( (dwLenOut > 0) && (NULL == pBufOut) )
{
return FALSE;
}
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:GET_SELF_ADDR +\r\n")));
PBYTE pbySelfAddr = (PBYTE) pBufOut;
*pbySelfAddr = pI2C->GetSelfAddress();
bRet = TRUE;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:GET_SELF_ADDR - Val=0x%x\r\n"), *pbySelfAddr));
break;
}
case I2C_IOCTL_TRANSFER:
{
#define MARSHAL 1
#if MARSHAL
DuplicatedBuffer_t Marshalled_pInBuf(pBufIn, dwLenIn, ARG_I_PTR);
pBufIn = reinterpret_cast<PBYTE>( Marshalled_pInBuf.ptr() );
if( (dwLenIn > 0) && (NULL == pBufIn) )
{
return FALSE;
}
#endif
I2C_TRANSFER_BLOCK *pXferBlock = (I2C_TRANSFER_BLOCK *) pBufIn;
if (pXferBlock->iNumPackets<=0)
{
return FALSE;
}
#if MARSHAL
MarshalledBuffer_t Marshalled_pPackets(pXferBlock->pI2CPackets,
pXferBlock->iNumPackets*sizeof(I2C_PACKET),
ARG_I_PTR);
I2C_PACKET *pPackets = reinterpret_cast<I2C_PACKET *>(Marshalled_pPackets.ptr());
if( (NULL == pPackets) )
{
return FALSE;
}
#else
I2C_PACKET *pPackets = pXferBlock->pI2CPackets;
#endif
#if MARSHAL
struct Marshalled_I2C_PACKET
{
MarshalledBuffer_t *pbyBuf;
MarshalledBuffer_t *lpiResult;
} *Marshalled_of_pPackets;
Marshalled_of_pPackets = new Marshalled_I2C_PACKET[pXferBlock->iNumPackets];
if (Marshalled_of_pPackets==0)
{
return FALSE;
}
MarshalledBuffer_t *pMarshalled_ptr;
int i;
// Map pointers for each packet in the array
for (i = 0; i < pXferBlock->iNumPackets; i++)
{
switch( pPackets[i].byRW )
{
case I2C_RW_WRITE:
pMarshalled_ptr = new MarshalledBuffer_t(
pPackets[i].pbyBuf,
pPackets[i].wLen,
ARG_I_PTR,
FALSE, FALSE);
if (pMarshalled_ptr ==0)
{
bRet = FALSE;
goto cleanupPass1;
}
if (pMarshalled_ptr->ptr()==0)
{
bRet = FALSE;
delete pMarshalled_ptr;
goto cleanupPass1;
}
break;
case I2C_RW_READ:
pMarshalled_ptr = new MarshalledBuffer_t(
pPackets[i].pbyBuf,
pPackets[i].wLen,
ARG_O_PTR, FALSE, FALSE);
if (pMarshalled_ptr ==0)
{
bRet = FALSE;
goto cleanupPass1;
}
if (pMarshalled_ptr->ptr()==0)
{
bRet = FALSE;
delete pMarshalled_ptr;
goto cleanupPass1;
}
break;
default:
{
bRet = FALSE;
goto cleanupPass1;
}
}
pPackets[i].pbyBuf = reinterpret_cast<PBYTE>(pMarshalled_ptr->ptr());
Marshalled_of_pPackets[i].pbyBuf = pMarshalled_ptr;
}
for (i = 0; i < pXferBlock->iNumPackets; i++)
{
pMarshalled_ptr = new MarshalledBuffer_t(
pPackets[i].lpiResult, sizeof(INT),
ARG_O_PDW, FALSE, FALSE);
if (pMarshalled_ptr ==0)
{
bRet = FALSE;
goto cleanupPass2;
}
if (pMarshalled_ptr->ptr()==0)
{
bRet = FALSE;
delete pMarshalled_ptr;
goto cleanupPass2;
}
pPackets[i].lpiResult = reinterpret_cast<LPINT>(pMarshalled_ptr->ptr());
Marshalled_of_pPackets[i].lpiResult = pMarshalled_ptr;
}
#endif
bRet = pI2C->ProcessPackets(pPackets, pXferBlock->iNumPackets);
#if MARSHAL
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:I2C_IOCTL_TRANSFER -\r\n")));
i = pXferBlock->iNumPackets;
cleanupPass2:
for (--i; i>=0; --i)
{
delete Marshalled_of_pPackets[i].lpiResult;
}
i = pXferBlock->iNumPackets;
cleanupPass1:
for (--i; i>=0; --i)
{
delete Marshalled_of_pPackets[i].pbyBuf;
}
delete[] Marshalled_of_pPackets;
#endif
break;
}
case I2C_IOCTL_RESET:
{
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:RESET +\r\n")));
pI2C->Reset();
bRet = TRUE;
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl:RESET -\r\n")));
break;
}
case I2C_IOCTL_ENABLE_SLAVE:
{
bRet = pI2C->EnableSlave();
break;
}
case I2C_IOCTL_DISABLE_SLAVE:
{
bRet = pI2C->DisableSlave();
break;
}
case I2C_IOCTL_SET_SLAVE_TXT:
{
// if the slave port is in idle, set the slave text for transmission
// the slave modified notification flag should also be cleared
if( (dwLenIn > 0) && (NULL == pBufIn) )
{
return FALSE;
}
bRet = pI2C->SetSlaveText(pBufIn, dwLenIn);
break;
}
case I2C_IOCTL_GET_SLAVE_TXT:
{
// read back the slave text after transmission
// the slave modified notification flag should also be cleared
if( (dwLenOut > 0) && (NULL == pBufOut) )
{
return FALSE;
}
bRet = pI2C->GetSlaveText(pBufOut, dwLenOut, pdwActualOut);
break;
}
case I2C_IOCTL_SET_SLAVESIZE:
{
if( (dwLenIn > 0) && (NULL == pBufIn) )
{
return FALSE;
}
// change slave text size
bRet = pI2C->SetSlaveSize(pBufIn, dwLenIn);
break;
}
case I2C_IOCTL_GET_SLAVESIZE:
{
if( (dwLenOut > 0) && (NULL == pBufOut) )
{
return FALSE;
}
DWORD dwActualOut;
bRet = pI2C->GetSlaveSize(pBufOut, dwLenOut, &dwActualOut);
break;
}
default:
{
bRet = FALSE;
break;
}
}
}
DEBUGMSG (ZONE_IOCTL|ZONE_FUNCTION, (TEXT("I2C_IOControl -\r\n")));
return bRet;
}
BOOL WINAPI I2C_DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
// Remove-W4: Warning C4100 workaround
UNREFERENCED_PARAMETER(lpvReserved);
switch (dwReason) {
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HINSTANCE) hInstDll);
DEBUGMSG(ZONE_FUNCTION, (TEXT("I2C_DllEntry: DLL_PROCESS_ATTACH lpvReserved(0x%x)\r\n"),lpvReserved));
DisableThreadLibraryCalls((HMODULE) hInstDll);
break;
case DLL_PROCESS_DETACH:
DEBUGMSG(ZONE_FUNCTION, (TEXT("I2C_DllEntry: DLL_PROCESS_DETACH lpvReserved(0x%x)\r\n"),lpvReserved));
break;
}
// return TRUE for success
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -