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

📄 i2c.cs

📁 This is a Windows CE 6.0 Board Support Package for the Gumstix Verdex platform
💻 CS
📖 第 1 页 / 共 2 页
字号:
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 + -