📄 i2c.cs
字号:
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Gumstix;
using OpenNETCF.IO;
namespace Gumstix
{
public class I2C : StreamInterfaceDriver
{
#region I2C device IOCTL codes
private enum RW : byte
{
WRITE = 1,
READ
}
private const Int32 FILE_DEVICE_BUS_EXTENDER = 0x0000002a;
private const Int32 FILE_ANY_ACCESS = 0x0;
private const Int32 METHOD_BUFFERED = 0x0;
private const Int32 CODE_IOCTL_SET_SLAVE_MODE = 3000; // Set I2C Bus to Slave Mode
private const Int32 CODE_IOCTL_SET_MASTER_MODE = 3001; // Set I2C Bus to Master Mode
private const Int32 CODE_IOCTL_IS_MASTER = 3002; // Is it in Master Mode?
private const Int32 CODE_IOCTL_IS_SLAVE = 3003; // Is it in Slave Mode?
private const Int32 CODE_IOCTL_SET_FAST_BUS = 3004; // Set Fast Bus Mode
private const Int32 CODE_IOCTL_IS_FAST_BUS = 3005; // Is it in Fast Bus Mode?
private const Int32 CODE_IOCTL_SET_SELF_ADDR = 3007; // Set My Address (Slave Mode)
private const Int32 CODE_IOCTL_GET_SELF_ADDR = 3008; // Get My Address (Slave Mode)
private const Int32 CODE_IOCTL_TRANSFER = 3009; // Transfer Data
private const Int32 CODE_IOCTL_RESET = 3010; // Software Reset
private const Int32 CODE_IOCTL_TRANSFER2 = 3015; // Transfer Data type 2
private const Int32 IOCTL_SET_SLAVE_MODE =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_SET_SLAVE_MODE) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_SET_MASTER_MODE =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_SET_MASTER_MODE) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_IS_MASTER =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_IS_MASTER) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_IS_SLAVE =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_IS_SLAVE) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_SET_FAST_BUS =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_SET_FAST_BUS) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_IS_FAST_BUS =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_IS_FAST_BUS) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_SET_SELF_ADDR =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_SET_SELF_ADDR) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_GET_SELF_ADDR =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_GET_SELF_ADDR) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_TRANSFER =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_TRANSFER) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_TRANSFER2 =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_TRANSFER2) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_RESET =
((FILE_DEVICE_BUS_EXTENDER) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_RESET) << 2) | (METHOD_BUFFERED);
#endregion
#region Native interface structures
[StructLayout(LayoutKind.Sequential)]
private struct Packet
{
public byte slaveAddress; // I2C slave device address for this I2C operation
public RW readWrite; // Read = I2C_READ or Write = I2C_WRITE
public IntPtr buffer;
public UInt16 length;
public IntPtr result; // Contains the result of last operation
public Packet(byte slaveAddress, RW readWrite, IntPtr data, int dataLength, IntPtr result)
{
this.slaveAddress = slaveAddress;
this.readWrite = readWrite;
this.buffer = data;
this.length = (UInt16)dataLength;
this.result = result;
}
}
#endregion
#region ctor / dtor
/// <summary>
/// Provides access to the I2C bus on the PXA270.
/// </summary>
public I2C() : base("I2C1:")
{
// open the driver
Open(FileAccess.ReadWrite, FileShare.ReadWrite);
}
~I2C()
{
// close the driver
Close();
}
#endregion
#region error handler
private void BusError(Int32 result)
{
switch (result)
{
case -7:
throw new Exception("No Acknowledge Issued:" + Marshal.GetLastWin32Error());
case -8:
throw new Exception("NULL Buffer:" + Marshal.GetLastWin32Error());
case -9:
throw new Exception("Invalid Buffer Size:" + Marshal.GetLastWin32Error());
case -10:
throw new Exception("NULL lpiResult field:" + Marshal.GetLastWin32Error());
case -11:
throw new Exception("CRM Operation Failure:" + Marshal.GetLastWin32Error());
case -12:
throw new Exception("I2C transmit timeout error:" + Marshal.GetLastWin32Error());
case -13:
throw new Exception("I2C arbitration lost error:" + Marshal.GetLastWin32Error());
}
}
#endregion
#region transfer
/// <summary>
/// Transfer one byte of data to the I2C bus
/// </summary>
/// <param name="address">Slave address</param>
/// <param name="data">Data byte</param>
public void Write(byte address, byte data)
{
Int32 result = 0;
IntPtr pResult = Marshal.AllocHGlobal(Marshal.SizeOf(result));
int rawsize = Marshal.SizeOf(data);
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.StructureToPtr(data, buffer, false);
Packet packet = new Packet(address, RW.WRITE, buffer, rawsize, pResult);
try
{
this.DeviceIoControl(IOCTL_TRANSFER2, SerializeToByteArray(packet), null);
result = (Int32)Marshal.PtrToStructure(pResult, typeof(Int32));
if (result < 0)
BusError(result);
}
catch (Exception)
{
throw new Exception("Unable to complete I2C transaction:" + Marshal.GetLastWin32Error());
}
finally
{
Marshal.FreeHGlobal(buffer);
Marshal.FreeHGlobal(pResult);
}
}
/// <summary>
/// Transfer two bytes (MSB first) to the I2C bus
/// </summary>
/// <param name="address">Slave address</param>
/// <param name="data">MSB transfered first</param>
public void Write(byte address, UInt16 data)
{
Int32 result = 0;
IntPtr pResult = Marshal.AllocHGlobal(Marshal.SizeOf(result));
int rawsize = Marshal.SizeOf(data);
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.StructureToPtr(data, buffer, false);
Packet packet = new Packet(address, RW.WRITE, buffer, rawsize, pResult);
try
{
this.DeviceIoControl(IOCTL_TRANSFER2, SerializeToByteArray(packet), null);
result = (Int32)Marshal.PtrToStructure(pResult, typeof(Int32));
if (result < 0)
BusError(result);
}
catch (Exception)
{
throw new Exception("Unable to complete I2C transaction:" + Marshal.GetLastWin32Error());
}
finally
{
Marshal.FreeHGlobal(buffer);
Marshal.FreeHGlobal(pResult);
}
}
/// <summary>
/// Transfer four bytes (MSB first) to the I2C bus
/// </summary>
/// <param name="address">Slave address</param>
/// <param name="data">MSB transfered first</param>
public void Write(byte address, UInt32 data)
{
Int32 result = 0;
IntPtr pResult = Marshal.AllocHGlobal(Marshal.SizeOf(result));
int rawsize = Marshal.SizeOf(data);
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.StructureToPtr(data, buffer, false);
Packet packet = new Packet(address, RW.WRITE, buffer, rawsize, pResult);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -