/PLATFORM/GumstixIII_BIN/VSProjects/GumstixManagedAPI/I2C.cs
# · C# · 462 lines · 343 code · 63 blank · 56 comment · 10 complexity · fc59e62eebb13c5b65dd0d4cd30b925f MD5 · raw file
- 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);
-
- 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 eight 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, UInt64 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>
- /// Read one byte of data from the I2C bus
- /// </summary>
- /// <param name="address">Slave address</param>
- /// <param name="data">reference to data byte</param>
- public void Read(byte address, ref byte data)
-
- {
- Int32 result = 0;
- IntPtr pResult = Marshal.AllocHGlobal(Marshal.SizeOf(result));
-
- int rawsize = Marshal.SizeOf(data);
- IntPtr buffer = Marshal.AllocHGlobal(rawsize);
-
- Packet packet = new Packet(address, RW.READ, buffer, rawsize, pResult);
-
- try
- {
- this.DeviceIoControl(IOCTL_TRANSFER2, SerializeToByteArray(packet), null);
- data = (Byte)Marshal.PtrToStructure(buffer, typeof(Byte));
- 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>
- /// Read two bytes from the I2C bus
- /// </summary>
- /// <param name="address">Slave address</param>
- /// <param name="data">reference to data word MSB contains first read byte</param>
- public void Read(byte address, ref UInt16 data)
- {
- Int32 result = 0;
- IntPtr pResult = Marshal.AllocHGlobal(Marshal.SizeOf(result));
-
- int rawsize = Marshal.SizeOf(data);
- IntPtr buffer = Marshal.AllocHGlobal(rawsize);
-
- Packet packet = new Packet(address, RW.READ, buffer, rawsize, pResult);
-
- try
- {
- this.DeviceIoControl(IOCTL_TRANSFER2, SerializeToByteArray(packet), null);
- data = (UInt16)Marshal.PtrToStructure(buffer, typeof(UInt16));
- 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>
- /// Read four bytes from the I2C bus
- /// </summary>
- /// <param name="address">Slave address</param>
- /// <param name="data">reference to data dword MSB contains first read byte</param>
- public void Read(byte address, ref UInt32 data)
- {
- Int32 result = 0;
- IntPtr pResult = Marshal.AllocHGlobal(Marshal.SizeOf(result));
-
- int rawsize = Marshal.SizeOf(data);
- IntPtr buffer = Marshal.AllocHGlobal(rawsize);
-
- Packet packet = new Packet(address, RW.READ, buffer, rawsize, pResult);
-
- try
- {
- this.DeviceIoControl(IOCTL_TRANSFER2, SerializeToByteArray(packet), null);
- data = (UInt32)Marshal.PtrToStructure(buffer, typeof(UInt32));
- 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>
- /// Read eight bytes from the I2C bus
- /// </summary>
- /// <param name="address">Slave address</param>
- /// <param name="data">reference to data qword MSB contains first read byte</param>
- public void Read(byte address, ref UInt64 data)
- {
- Int32 result = 0;
- IntPtr pResult = Marshal.AllocHGlobal(Marshal.SizeOf(result));
-
- int rawsize = Marshal.SizeOf(data);
- IntPtr buffer = Marshal.AllocHGlobal(rawsize);
-
- Packet packet = new Packet(address, RW.READ, buffer, rawsize, pResult);
-
- try
- {
- this.DeviceIoControl(IOCTL_TRANSFER2, SerializeToByteArray(packet), null);
- data = (UInt64)Marshal.PtrToStructure(buffer, typeof(UInt64));
- 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);
- }
- }
-
- #endregion
-
- #region P/Invoke helpers
-
- /// <summary>
- /// Byte array serializer
- /// </summary>
- /// <param name="anything"></param>
- /// <returns></returns>
- private static byte[] SerializeToByteArray(object anything)
- {
- int rawsize = Marshal.SizeOf(anything);
- IntPtr buffer = Marshal.AllocHGlobal(rawsize);
- Marshal.StructureToPtr(anything, buffer, false);
- byte[] rawdatas = new byte[rawsize];
- Marshal.Copy(buffer, rawdatas, 0, rawsize);
- Marshal.FreeHGlobal(buffer);
- return rawdatas;
- }
-
- /// <summary>
- /// De-serializer from byte array
- /// </summary>
- /// <param name="rawdatas"></param>
- /// <param name="anytype"></param>
- /// <returns></returns>
- private static object DeserializeFromByteArray(byte[] rawdatas, Type anytype)
- {
- int rawsize = Marshal.SizeOf(anytype);
- if (rawsize > rawdatas.Length)
- return null;
- IntPtr buffer = Marshal.AllocHGlobal(rawsize);
- Marshal.Copy(rawdatas, 0, buffer, rawsize);
- object retobj = Marshal.PtrToStructure(buffer, anytype);
- Marshal.FreeHGlobal(buffer);
- return retobj;
- }
- #endregion
- }
- }