⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c_io.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//          [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 + -