前言
刚刚完成一个WINCE 下的I2C的流驱动,由于在读I2C 时要进行参数的传入和传出,所以其中的xx_IOControl必须要完成,像一些简单的传递单向数据的驱动,要xx_Read或xx_Write就可以实现.
之前没有写过xx_IOControl,所以参考了网上的代码又结合自己的软硬件环境,我现有的BSP 里已经实现了I2C 读写的基本函数,所以只需要我驱动了作好初始化,并处理好读写I2C 之前的工作,正确的传入参数,正确的调用现有的i2c读写函数就可以了.
说明下,我访问的I2C 从器件是eeprom :CAT24C04.功能只实现简单的读byte和写byte.
准备工作:了解IOControl 的使用,这里引用下其他人的总结
=========引用开始=================================
原文地址: http://hi.baidu.com/magical/blog/item/3e6746103ea036f9c2ce79c0.html
应用程序和驱动程序的通信过程是:应用程序使用CreateFile函数打开设备,然后用DeviceIoControl与驱动程序进行通信,包括读和写两种操作。还可以用ReadFile读数据用WriteFile写数据。操作完毕时用CloseHandle关闭设备。我们比较常用的就是用DeviceIoControl对设备进行读写操作。先看看DeviceIoControl是怎么定义的: BOOL DeviceIoControl( HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped ); Parameters(参数)
Return Values(返回值)Nonzero indicates success. Zero indicates failure. To obtain extended error information, call the GetLastError function. (非0成功,0失败) 具体使用我们看看列子: 1,向设备传递数据,我们定义一个函数来实现 bool CDeviceOperDlg::SendKeyData(HANDLE handle, BYTE *bData, int iSize) //将数据放置到发送数组 &nOutput, return true; 2,从设备读取数据
ULONG nOutput; |
==================引用结束===============================
现在开始我的代码
驱动代码实现:
oemi2c_write与 oemi2c_read ,其中XllpI2CWrite和XllpI2CRead是BSP实现得代码.
- int oemi2c_write(XLLP_UINT8_T slaveAddr, XLLP_UINT8_T * bytesBuf, int bytesCount)
- {
- int status;
- Lock();
- status = XllpI2CWrite((P_XLLP_I2C_T)(m_I2CBase),(P_XLLP_OST_T)(m_OSTBase),slaveAddr,bytesBuf,bytesCount,1);
- if (status != XLLP_STATUS_SUCCESS) {
- RETAILMSG(1, (TEXT("I2C: XllpI2CWrite failed %d/r/n"), status));
- }
- UnLock();
- return status;
- }
- int oemi2c_read(XLLP_UINT8_T slaveAddr, XLLP_UINT8_T subAddr,XLLP_UINT8_T * bytesBuf, int bytesCount)
- {
- int status;
- Lock();
- status = XllpI2CWrite((P_XLLP_I2C_T)(m_I2CBase), (P_XLLP_OST_T)(m_OSTBase),slaveAddr,&subAddr,1,1);
- if (status != XLLP_STATUS_SUCCESS) {
- RETAILMSG(1, (TEXT("I2C:1 XllpI2CWrite failed %d/r/n"), status));
- }
- status = XllpI2CRead((P_XLLP_I2C_T)(m_I2CBase), (P_XLLP_OST_T)(m_OSTBase),slaveAddr,bytesBuf,bytesCount,1);
- if (status != XLLP_STATUS_SUCCESS) {
- RETAILMSG(1, (TEXT("I2C:2 XllpI2CRead failed %d/r/n"), status));
- }
- UnLock();
- return status;
- }
IIC_IOControl函数
-
- typedef struct _I2C_IO_DESC
- {
- DWORD SlaveAddr; // Target Slave Address
- DWORD WordAddr; // Starting Slave Word Address
- //LPBYTE pData; // pBuffer
- XLLP_UINT8_T *pData;
- XLLP_UINT32_T Count; // nBytes to read/write
- } I2C_IO_DESC, *PI2C_IO_DESC;
- #define IOCTL_I2C_READ 1
- #define IOCTL_I2C_WRITE 4
- BOOL IIC_IOControl(DWORD hOpenContext,DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
- {
- DWORD dwErr = ERROR_SUCCESS;
- BOOL bRc = TRUE;
- XLLP_UINT8_T *pval;//received data
- XLLP_UINT8_T Address,SlaveAddr,ActiveAdress;
- I2C_IO_DESC *pI2C_Desc;
- XLLP_STATUS_T status;
- XLLP_UINT8_T WRbuf[2];
- RETAILMSG(ZONE_IIC,(TEXT(">IIC -IOControl(0x%x,0x%x, 0x%x, %d, 0x%x)/n"),
- dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut ));
- if ( !m_I2CBase || !g_OpenCount )
- {
- RETAILMSG (1, (TEXT("IIC-IOControl: ERROR_INVALID_HANDLE/r/n")));
- SetLastError (ERROR_INVALID_HANDLE);
- return(FALSE);
- }
- if (pdwActualOut)
- *pdwActualOut = 0;
- //--------------------------------------------
- switch (dwCode)
- {
- case IOCTL_I2C_READ:
- if ( (dwLenIn < sizeof(I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->pData )
- {
- dwErr = ERROR_INVALID_PARAMETER;
- bRc = FALSE;
- RETAILMSG (1, (TEXT("1:IOCTL_I2C_READ: ERROR_INVALID_PARAMETER/r/n")));
- break;
- }
- pI2C_Desc=(PI2C_IO_DESC)MapPtrToProcess(pBufIn,(HANDLE) GetCurrentProcess()); //得到传入参数
- if (pBufIn != NULL && pI2C_Desc == NULL)
- {
- // Security violation
- RETAILMSG(1, (TEXT("I2CRead>Failed to map pointer to caller/r/n")));
- dwErr = ERROR_INVALID_PARAMETER;
- RETAILMSG (1, (TEXT("2:IOCTL_I2C_READ: ERROR_INVALID_PARAMETER/r/n")));
- bRc = FALSE;
- break;
- }
- pval=(XLLP_UINT8_T *)MapPtrToProcess(pI2C_Desc->pData,(HANDLE) GetCurrentProcess());
- if (pI2C_Desc->pData != NULL && pval == NULL)
- {
- // Security violation
- RETAILMSG(1, (TEXT("I2CRead>Failed to map pointer to caller/r/n")));
- dwErr = ERROR_INVALID_PARAMETER;
- RETAILMSG (1, (TEXT("3:IOCTL_I2C_READ: ERROR_INVALID_PARAMETER/r/n")));
- bRc = FALSE;
- break;
- }
- Address =(XLLP_UINT8_T)(pI2C_Desc->WordAddr);
- ActiveAdress = (Address & 0xFF);
- SlaveAddr = (XLLP_UINT8_T)(pI2C_Desc->SlaveAddr);// | (((dwAddress/255)&0x07)<<1));
- WRbuf[0]=*pval;
- status=oemi2c_read(SlaveAddr,ActiveAdress,WRbuf,1);//read one byte
- *pBufOut=WRbuf[0];//输出的数据
- *pdwActualOut=1;//READ ONE BYTE
- if(status!=XLLP_STATUS_SUCCESS)
- {
- bRc = FALSE;
- RETAILMSG (1, (TEXT("4 IOCTL_I2C_READ error: /r/n")));
- break;
- }
- UnMapPtr(pval);
- UnMapPtr(pI2C_Desc);
- break;
- case IOCTL_I2C_WRITE:
- if ( (dwLenIn < sizeof(I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->pData)
- {
- dwErr = ERROR_INVALID_PARAMETER;
- RETAILMSG (1, (TEXT("1 IOCTL_I2C_WRITE ERROR_INVALID_PARAMETER/r/n")));
- bRc = FALSE;
- break;
- }
- pI2C_Desc=(PI2C_IO_DESC)MapPtrToProcess(pBufIn,(HANDLE) GetCurrentProcess());
- if (pBufIn != NULL && pI2C_Desc == NULL)
- {
- // Security violation
- RETAILMSG(1, (TEXT("I2CRead>Failed to map pointer to caller/r/n")));
- dwErr = ERROR_INVALID_PARAMETER;
- bRc = FALSE;
- RETAILMSG (1, (TEXT("2 IOCTL_I2C_WRITE ERROR_INVALID_PARAMETER/r/n")));
- break;
- }
- pval=(XLLP_UINT8_T *)MapPtrToProcess(pI2C_Desc->pData,(HANDLE) GetCurrentProcess());
- if (pI2C_Desc->pData != NULL && pval == NULL)
- {
- // Security violation
- RETAILMSG(1, (TEXT("I2CRead>Failed to map pointer to caller/r/n")));
- dwErr = ERROR_INVALID_PARAMETER;
- bRc = FALSE;
- RETAILMSG (1, (TEXT("3 IOCTL_I2C_WRITE ERROR_INVALID_PARAMETER/r/n")));
- break;
- }
- Address = (XLLP_UINT8_T)(pI2C_Desc->WordAddr);
- ActiveAdress = (Address & 0xFF);
- SlaveAddr = (XLLP_UINT8_T)(pI2C_Desc->SlaveAddr );//| (((dwAddress/255)&0x07)<<1));
- //begain I2C
- WRbuf[0] = ActiveAdress;
- WRbuf[1] = *pval;
- status=oemi2c_write(SlaveAddr,WRbuf,2);//write one byte
- *pdwActualOut =1;
- if(status!= XLLP_STATUS_SUCCESS)
- { bRc = FALSE;
- RETAILMSG (1, (TEXT("4 IOCTL_I2C_WRITE ERror/r/n")));
- break;
- }
- UnMapPtr(pval);
- UnMapPtr(pI2C_Desc);
- break;
- default:
- bRc = FALSE;
- dwErr = ERROR_INVALID_FUNCTION;
- RETAILMSG (1, (TEXT("I2C_IOControl Unknown Ioctl: 0x%X/r/n"), dwCode));
- break;
- }
- //-------------------------------------
- if ( !bRc )
- {
- RETAILMSG (1, (TEXT("I2C_IOControl ERROR: %u/r/n"), dwErr));
- SetLastError(dwErr);
- }
- RETAILMSG(ZONE_IIC,(TEXT("<I2C_IOControl:%d/n"), bRc));
- return bRc;;
- }
========================================================
EVC 应用程序代码:
typedef struct _I2C_IO_DESC
{
DWORD SlaveAddr; // Target Slave Address
DWORD WordAddr; // Starting Slave Word Address
//LPBYTE pData; // pBuffer
unsigned char *pData;
unsigned long Count; // nBytes to read/write
} I2C_IO_DESC, *PI2C_IO_DESC;
#define IOCTL_I2C_READ 1
#define IOCTL_I2C_WRITE 4
#define CAT24C04Addr (0x0a0>>1)
DWORD RetBytes;
I2C_IO_DESC DataFamily;
- // Cpage_i2c message handlers
- BOOL Cpage_i2c::OnInitDialog()
- {
- CPropertyPage::OnInitDialog();
- // TODO: Add extra initialization here
- m_hIIC=CreateFile(TEXT("IIC1:"),GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,NULL,NULL);
- if(m_hIIC==INVALID_HANDLE_VALUE)
- {
- AfxMessageBox(_T("I2C CreateFile failed!!"));
- return 0;
- }
- return TRUE; // return TRUE unless you set the focus to a control
- // EXCEPTION: OCX Property Pages should return FALSE
- }
- //----write byte button--------------
- void Cpage_i2c::OnBUTTONi2cWB()
- {
- // TODO: Add your control notification handler code here
- // AfxMessageBox(_T("I2C OnBUTTON i2c WB!!"));
- DWORD Ret;
- UpdateData(true);
- pBuffOut[0]=(unsigned char)m_i2cWrData;
- DataFamily.SlaveAddr=CAT24C04Addr;
- DataFamily.WordAddr=(unsigned char)m_i2cWrAddr;
- DataFamily.pData=pBuffOut;
- DataFamily.Count=1;
- Ret=DeviceIoControl(m_hIIC,IOCTL_I2C_WRITE,&DataFamily,sizeof(DataFamily),NULL,0,&RetBytes,NULL); //
- if(!Ret)
{
AfxMessageBox(_T("I2C communication error!!"));
return;
} - }
- //----read byte button--------------
- void Cpage_i2c::OnBUTTONi2cRB()
- {
- // TODO: Add your control notification handler code here
- // AfxMessageBox(_T("I2C OnBUTTON i2c RB!!"));
- BYTE poutBuff[2]={0,0};
- DWORD Ret;
- UpdateData(true);
- DataFamily.SlaveAddr=CAT24C04Addr;
- DataFamily.WordAddr=(unsigned char)m_i2cRdAddr;
- DataFamily.pData=pBuffin;
- DataFamily.Count=1;
- Ret=DeviceIoControl(m_hIIC,IOCTL_I2C_READ,&DataFamily,sizeof(DataFamily),poutBuff,1,&RetBytes,NULL); //
- if(!Ret)
{
AfxMessageBox(_T("I2C communication error!!"));
return;
} - m_i2cRdData=poutBuff[0]; //收到得数据
- UpdateData(FALSE);
- }
运行界面: