IIC驱动

WINCE 流驱动的xx_IOControl 收藏

 

前言

       刚刚完成一个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

DeviceIoControl的使用说明
2008-07-15 10:57

 

        应用程序和驱动程序的通信过程是:应用程序使用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(参数)
hDevice (CreateFile返回的设备句柄)
[in] Handle to the device that is to perform the operation. To obtain a device handle, call the CreateFile function.
dwIoControlCode (应用程序调用驱动程序的控制命令,就是IOCTL_XXX IOCTLs )
[in] IOCTL for the operation. This value identifies the specific operation to perform and the type of device on which to perform the operation. There are no specific values defined for the dwIoControlCode parameter. However, you can define custom IOCTL_XXX IOCTLs with the CTL_CODE macro. You can then advertise these IOCTLs and an application can use these IOCTLs with DeviceIoControl to perform the driver-specific functions.
lpInBuffer (应用程序传递给驱动程序的数据缓冲区地址)
[in] Long pointer to a buffer that contains the data required to perform the operation. Set to NULL if the dwIoControlCode parameter specifies an operation that does not require input data.
nInBufferSize (应用程序传递给驱动程序的数据缓冲区大小,字节数)
[in] Size, in bytes, of the buffer pointed to by lpInBuffer.
lpOutBuffer (驱动程序返回给应用程序的数据缓冲区地址)
[out] Long pointer to a buffer that receives the output data for the operation. Set to NULL if the dwIoControlCode parameter specifies an operation that does not produce output data.
nOutBufferSize (驱动程序返回给应用程序的数据缓冲区大小,字节数)
[out] Size, in bytes, of the buffer pointed to by lpOutBuffer.
lpBytesReturned (驱动程序实际返回给应用程序的数据字节数地址)
[out] Long pointer to a variable that receives the size, in bytes, of the data stored in lpOutBuffer. The DeviceIoControl function may unnecessarily use this parameter. For example, if an operation does not produce data for lpOutBuffer and lpOutBuffer is NULL, the value of lpBytesReturned is meaningless.
lpOverlapped (重叠操作结构)
[in] Ignored; set to NULL.
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)
{
ULONG nOutput;
BYTE bTemp[512];

//将数据放置到发送数组
memset(bTemp,0,sizeof(bTemp));
memcpy(bTemp,&bData[0],iSize);
//向设备发送
if (!DeviceIoControl(handle,        
       ATST2004_IOCTL_WRITE,     //根据具体的设备有相关的定义
       bTemp,                                        //向设备传递的数据地址
       iSize,                                            //数据大小,字节数
       NULL,                                          //没有返回的数据,置为NULL
       0,                                                  //没有返回的数据,置为0

       &nOutput,
       NULL)
    )
{
   return false;
}

return true;
}

2,从设备读取数据


bool CDeviceOperDlg::ReviceKeyData(HANDLE handle, BYTE *bData, int iSize)
{

ULONG nOutput;
BYTE bTemp[512];
//数组清零
memset(bTemp,0,sizeof(bTemp));
//向设备发送
if (!DeviceIoControl(handle,
       ATST2004_IOCTL_READ,           //根据具体的设备有相关的定义
       NULL,                                              //没有向设备传递的数据,置为NULL
       0,                                                      //没有向设备传递的数据,置为NULL
       bTemp,                                            //读取设备的数据返回地址
       iSize,                                                //读取数据的字节数
       &nOutput,
       NULL)
    )
{
   return false;
}
//放置到公用数组
memcpy(&bData[0],&bTemp[0],iSize);
return true;
}

==================引用结束===============================

现在开始我的代码

驱动代码实现:

 oemi2c_write与 oemi2c_read ,其中XllpI2CWrite和XllpI2CRead是BSP实现得代码.

  1. int   oemi2c_write(XLLP_UINT8_T slaveAddr, XLLP_UINT8_T * bytesBuf,  int  bytesCount)
  2. {
  3.      int  status;
  4.     Lock();
  5.     status = XllpI2CWrite((P_XLLP_I2C_T)(m_I2CBase),(P_XLLP_OST_T)(m_OSTBase),slaveAddr,bytesBuf,bytesCount,1);
  6.      if  (status != XLLP_STATUS_SUCCESS) {
  7.         RETAILMSG(1, (TEXT( "I2C: XllpI2CWrite failed %d/r/n" ), status));
  8.     }
  9.      UnLock();
  10.      return  status;
  11. }
  12. int  oemi2c_read(XLLP_UINT8_T slaveAddr, XLLP_UINT8_T subAddr,XLLP_UINT8_T * bytesBuf,  int  bytesCount)
  13. {
  14.      int   status;
  15.     Lock();
  16.     status = XllpI2CWrite((P_XLLP_I2C_T)(m_I2CBase), (P_XLLP_OST_T)(m_OSTBase),slaveAddr,&subAddr,1,1);
  17.      if  (status != XLLP_STATUS_SUCCESS) {
  18.         RETAILMSG(1, (TEXT( "I2C:1  XllpI2CWrite failed %d/r/n" ), status));
  19.     }
  20.     status = XllpI2CRead((P_XLLP_I2C_T)(m_I2CBase), (P_XLLP_OST_T)(m_OSTBase),slaveAddr,bytesBuf,bytesCount,1);
  21.      if  (status != XLLP_STATUS_SUCCESS) {
  22.         RETAILMSG(1, (TEXT( "I2C:2  XllpI2CRead failed %d/r/n" ), status));
  23.     }
  24.      UnLock();
  25.      return  status;
  26. }

IIC_IOControl函数

    1. typedef   struct  _I2C_IO_DESC  
    2.   DWORD  SlaveAddr;  // Target Slave Address 
    3.   DWORD  WordAddr;  // Starting Slave Word Address 
    4.   //LPBYTE  pData; // pBuffer 
    5.  XLLP_UINT8_T *pData; 
    6.  XLLP_UINT32_T Count;  // nBytes to read/write 
    7. } I2C_IO_DESC, *PI2C_IO_DESC; 
    8. #define IOCTL_I2C_READ 1 
    9. #define IOCTL_I2C_WRITE 4 
    10. BOOL  IIC_IOControl( DWORD  hOpenContext, DWORD  dwCode, PBYTE  pBufIn, DWORD  dwLenIn, PBYTE  pBufOut, DWORD  dwLenOut,PDWORD pdwActualOut) 
    11.   DWORD  dwErr = ERROR_SUCCESS; 
    12.       BOOL   bRc = TRUE; 
    13.  XLLP_UINT8_T *pval; //received data 
    14.  XLLP_UINT8_T Address,SlaveAddr,ActiveAdress; 
    15.  I2C_IO_DESC *pI2C_Desc; 
    16.  XLLP_STATUS_T status; 
    17.  XLLP_UINT8_T WRbuf[2]; 
    18.      RETAILMSG(ZONE_IIC,(TEXT( ">IIC -IOControl(0x%x,0x%x, 0x%x, %d, 0x%x)/n" ), 
    19.         dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut )); 
    20.      if  ( !m_I2CBase || !g_OpenCount )  
    21.   { 
    22.            RETAILMSG (1, (TEXT( "IIC-IOControl: ERROR_INVALID_HANDLE/r/n" ))); 
    23.           SetLastError (ERROR_INVALID_HANDLE); 
    24.            return (FALSE); 
    25.       } 
    26.       if  (pdwActualOut) 
    27.          *pdwActualOut = 0; 
    28.       //--------------------------------------------  
    29.       switch  (dwCode)  
    30.   { 
    31.      case  IOCTL_I2C_READ: 
    32.                if  ( (dwLenIn <  sizeof (I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->pData )  
    33.     { 
    34.                    dwErr = ERROR_INVALID_PARAMETER; 
    35.                    bRc = FALSE; 
    36.      RETAILMSG (1, (TEXT( "1:IOCTL_I2C_READ: ERROR_INVALID_PARAMETER/r/n" ))); 
    37.                    break
    38.                } 
    39.    pI2C_Desc=(PI2C_IO_DESC)MapPtrToProcess(pBufIn,( HANDLE ) GetCurrentProcess());  //得到传入参数 
    40.     if  (pBufIn != NULL && pI2C_Desc == NULL)  
    41.     { 
    42.       // Security violation 
    43.      RETAILMSG(1, (TEXT( "I2CRead>Failed to map pointer to caller/r/n" ))); 
    44.                   dwErr = ERROR_INVALID_PARAMETER; 
    45.      RETAILMSG (1, (TEXT( "2:IOCTL_I2C_READ: ERROR_INVALID_PARAMETER/r/n" ))); 
    46.                    bRc = FALSE; 
    47.                     break
    48.     }  
    49.    pval=(XLLP_UINT8_T *)MapPtrToProcess(pI2C_Desc->pData,( HANDLE ) GetCurrentProcess()); 
    50.     if  (pI2C_Desc->pData != NULL && pval == NULL)  
    51.     { 
    52.       // Security violation 
    53.      RETAILMSG(1, (TEXT( "I2CRead>Failed to map pointer to caller/r/n" ))); 
    54.                    dwErr = ERROR_INVALID_PARAMETER; 
    55.      RETAILMSG (1, (TEXT( "3:IOCTL_I2C_READ: ERROR_INVALID_PARAMETER/r/n" ))); 
    56.                   bRc = FALSE; 
    57.                    break
    58.     } 
    59.               Address =(XLLP_UINT8_T)(pI2C_Desc->WordAddr); 
    60.    ActiveAdress = (Address & 0xFF); 
    61.    SlaveAddr = (XLLP_UINT8_T)(pI2C_Desc->SlaveAddr); // | (((dwAddress/255)&0x07)<<1)); 
    62.     WRbuf[0]=*pval; 
    63.    status=oemi2c_read(SlaveAddr,ActiveAdress,WRbuf,1); //read one byte 
    64.    *pBufOut=WRbuf[0]; //输出的数据 
    65.    *pdwActualOut=1; //READ ONE BYTE 
    66.     if (status!=XLLP_STATUS_SUCCESS) 
    67.     { 
    68.      bRc = FALSE; 
    69.      RETAILMSG (1, (TEXT( "4 IOCTL_I2C_READ error: /r/n" ))); 
    70.       break
    71.     } 
    72.               UnMapPtr(pval); 
    73.               UnMapPtr(pI2C_Desc);    
    74.     break
    75.     
    76.    case  IOCTL_I2C_WRITE: 
    77.     if  ( (dwLenIn <  sizeof (I2C_IO_DESC)) || !pBufIn || !((PI2C_IO_DESC)pBufIn)->pData)  
    78.     { 
    79.                    dwErr = ERROR_INVALID_PARAMETER; 
    80.      RETAILMSG (1, (TEXT( "1 IOCTL_I2C_WRITE ERROR_INVALID_PARAMETER/r/n" ))); 
    81.                    bRc = FALSE; 
    82.                     break
    83.                } 
    84.    pI2C_Desc=(PI2C_IO_DESC)MapPtrToProcess(pBufIn,( HANDLE ) GetCurrentProcess()); 
    85.     if  (pBufIn != NULL && pI2C_Desc == NULL)  
    86.     { 
    87.       // Security violation 
    88.      RETAILMSG(1, (TEXT( "I2CRead>Failed to map pointer to caller/r/n" ))); 
    89.                   dwErr = ERROR_INVALID_PARAMETER; 
    90.                    bRc = FALSE; 
    91.      RETAILMSG (1, (TEXT( "2 IOCTL_I2C_WRITE ERROR_INVALID_PARAMETER/r/n" ))); 
    92.                     break
    93.     }  
    94.    pval=(XLLP_UINT8_T *)MapPtrToProcess(pI2C_Desc->pData,( HANDLE ) GetCurrentProcess()); 
    95.     if  (pI2C_Desc->pData != NULL && pval == NULL)  
    96.     { 
    97.       // Security violation 
    98.      RETAILMSG(1, (TEXT( "I2CRead>Failed to map pointer to caller/r/n" ))); 
    99.                    dwErr = ERROR_INVALID_PARAMETER; 
    100.                   bRc = FALSE; 
    101.      RETAILMSG (1, (TEXT( "3 IOCTL_I2C_WRITE ERROR_INVALID_PARAMETER/r/n" ))); 
    102.                    break
    103.     } 
    104.    Address = (XLLP_UINT8_T)(pI2C_Desc->WordAddr); 
    105.    ActiveAdress = (Address & 0xFF); 
    106.    SlaveAddr = (XLLP_UINT8_T)(pI2C_Desc->SlaveAddr ); //| (((dwAddress/255)&0x07)<<1)); 
    107.     //begain I2C 
    108.    WRbuf[0] = ActiveAdress; 
    109.    WRbuf[1] = *pval; 
    110.     status=oemi2c_write(SlaveAddr,WRbuf,2); //write one byte 
    111.     *pdwActualOut =1; 
    112.     if (status!= XLLP_STATUS_SUCCESS) 
    113.     { bRc = FALSE; 
    114.      RETAILMSG (1, (TEXT( "4 IOCTL_I2C_WRITE ERror/r/n" ))); 
    115.       break
    116.     } 
    117.    UnMapPtr(pval); 
    118.               UnMapPtr(pI2C_Desc);    
    119.     break
    120.    default
    121.    bRc  = FALSE; 
    122.               dwErr = ERROR_INVALID_FUNCTION; 
    123.               RETAILMSG (1, (TEXT( "I2C_IOControl Unknown Ioctl: 0x%X/r/n" ), dwCode)); 
    124.     break
    125.       } 
    126.   //------------------------------------- 
    127.   if  ( !bRc ) 
    128.  { 
    129.          RETAILMSG (1, (TEXT( "I2C_IOControl ERROR: %u/r/n" ), dwErr)); 
    130.          SetLastError(dwErr); 
    131.      } 
    132.      RETAILMSG(ZONE_IIC,(TEXT( "<I2C_IOControl:%d/n" ), bRc)); 
    133.   return  bRc;; 
    134. }

========================================================

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;

  1. // Cpage_i2c message handlers
  2. BOOL  Cpage_i2c::OnInitDialog() 
  3. {
  4.  CPropertyPage::OnInitDialog();
  5.   // TODO: Add extra initialization here
  6.  m_hIIC=CreateFile(TEXT( "IIC1:" ),GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,NULL,NULL);
  7.   if (m_hIIC==INVALID_HANDLE_VALUE)
  8.  {
  9.   AfxMessageBox(_T( "I2C CreateFile failed!!" ));
  10.    return  0;
  11.  }
  12.   return  TRUE;   // return TRUE unless you set the focus to a control
  13.                 // EXCEPTION: OCX Property Pages should return FALSE
  14. }
  15. //----write byte button--------------
  16. void  Cpage_i2c::OnBUTTONi2cWB() 
  17. {
  18.   // TODO: Add your control notification handler code here
  19. // AfxMessageBox(_T("I2C OnBUTTON i2c WB!!"));
  20.   DWORD  Ret;
  21.  UpdateData( true );
  22.  pBuffOut[0]=(unsigned  char )m_i2cWrData;
  23.  DataFamily.SlaveAddr=CAT24C04Addr;
  24.  DataFamily.WordAddr=(unsigned  char )m_i2cWrAddr;
  25.  DataFamily.pData=pBuffOut;
  26.  DataFamily.Count=1;  
  27.     Ret=DeviceIoControl(m_hIIC,IOCTL_I2C_WRITE,&DataFamily, sizeof (DataFamily),NULL,0,&RetBytes,NULL);   //
  28.  if(!Ret)
     {
      AfxMessageBox(_T("I2C communication error!!"));
      return;
     }
  29. }
  30. //----read byte button--------------
  31. void  Cpage_i2c::OnBUTTONi2cRB() 
  32. {
  33.   // TODO: Add your control notification handler code here
  34.   // AfxMessageBox(_T("I2C OnBUTTON i2c RB!!"));
  35.   BYTE   poutBuff[2]={0,0};
  36.   DWORD  Ret;
  37.  UpdateData( true );
  38.  DataFamily.SlaveAddr=CAT24C04Addr;
  39.  DataFamily.WordAddr=(unsigned  char )m_i2cRdAddr;
  40.  DataFamily.pData=pBuffin;
  41.  DataFamily.Count=1;  
  42.     Ret=DeviceIoControl(m_hIIC,IOCTL_I2C_READ,&DataFamily, sizeof (DataFamily),poutBuff,1,&RetBytes,NULL);   //
  43.  if(!Ret)
     {
      AfxMessageBox(_T("I2C communication error!!"));
      return;
     }
  44.  m_i2cRdData=poutBuff[0];  //收到得数据
  45.  UpdateData(FALSE); 
  46. }

运行界面:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值