David's Random Projects and Documents
Feel free to use and link to any docs you find here. Please give credit and link back to this page on any publicly avaliable copies.

C# I2C Library for the Intel Edison

Edison I2C library using Intel's MRAA Library.
Thanks to Wanjun Gao for sharing his functional I2C code which this is based on.

Usage

Device Initialization

using Edison.IO;
...
MRAA.Initialize(); //This should only be called once
...
I2C i2c1 = I2C.Initialize(1); //Initialize and get object for i2c1 interface
i2c1.Frequency = I2C.Mode.Standard; //Set I2C interface in 100 kHz mode ...

Reading and Writing data

//Write byte to device with address 10
i2c1.Address = 10;
i2c1.WriteByte(0xef);

//Write block to device with previous address
byte[] buffer = {0x20, 0x28, 0x30, 0x38};
i2c1.Write(buffer);

//Read byte from device with address 20
i2c1.Address = 20;
byte data = i2c1.ReadByte();

//Read 6 bytes from device with address 21
byte[] buffer = new byte[6];
i2c1.Address = 21;
int bytesRead = i2c1.Read(buffer);
if (bytesRead != 6) //Verify correct number of bytes were read
  ... //Error handling

Cleanup

i2c1.Close();
...
//On program close
MRAA.Deinitialize(); //This line is not required normaly see MRAA Lib for details

Source

using System;
using System.Runtime.InteropServices;

namespace Edison.IO
{
    public class I2C : IDisposable
    {
        #region Enumerations
        public enum Mode : int
        {
            /// <summary>
            /// Standard sets speed up to 100 kHz
            /// </summary>
            Standard = 0,
            /// <summary>
            /// Fast sets speed up t0 400 kHz
            /// </summary>
            Fast = 1,
            /// <summary>
            /// High sets speed up to 3.4 MHz
            /// </summary>
            High = 2
        }
        #endregion

        #region Variables
        private IntPtr device = IntPtr.Zero;
        #endregion

        #region Accessors
        public Mode Frequency
        {
            set
            {
                var result = mraa_i2c_frequency(this.device, value);
                if (result != MRAA.Result.Success)
                    throw new MRAAException(result);
            }
        }
        public byte Address
        {
            set
            {
                var result = mraa_i2c_address(this.device, value);
                if (result != MRAA.Result.Success)
                    throw new MRAAException(result);
            }
        }
        #endregion

        #region Constructors and Initialization
        private I2C(IntPtr dev)
        {
            this.device = dev;
        }

        public static I2C Initialize(int bus)
        {
            IntPtr dev = mraa_i2c_init(bus);
            if (dev == IntPtr.Zero)
                throw new MRAAException(MRAA.Result.ErrorUnspecified);
            return new I2C(dev);
        }
        #endregion

        #region Read
        public int Read(byte[] buffer)
        {
            return mraa_i2c_read(this.device, buffer, buffer.Length);
        }

        public byte ReadByte()
        {
            return mraa_i2c_read_byte(this.device);
        }
        #endregion

        #region Write
        public void Write(byte[] buffer)
        {
            var result = mraa_i2c_write(this.device, buffer, buffer.Length);
            if (result != MRAA.Result.Success)
                throw new MRAAException(result);
        }

        public void WriteByte(byte value)
        {
            var result = mraa_i2c_write_byte(this.device, value);
            if (result != MRAA.Result.Success)
                throw new MRAAException(result);
        }
        #endregion

        #region Cleanup
        public void Close()
        {
            if (this.device == IntPtr.Zero)
                return;
            mraa_i2c_stop(this.device);
            this.device = IntPtr.Zero;
        }

        public void Dispose()
        {
            if (this.device != IntPtr.Zero)
                this.Close();
        }
        #endregion

        #region External Functions
        [DllImport("libmraa.so")]
        private static extern IntPtr mraa_i2c_init(int bus);

        [DllImport("libmraa.so")]
        private static extern void mraa_i2c_stop(IntPtr device);

        [DllImport("libmraa.so")]
        private static extern MRAA.Result mraa_i2c_frequency(IntPtr device, Mode mode);

        [DllImport("libmraa.so")]
        private static extern MRAA.Result mraa_i2c_address(IntPtr device, byte address);

        [DllImport("libmraa.so")]
        private static extern int mraa_i2c_read(IntPtr device, byte[] data, int length);

        [DllImport("libmraa.so")]
        private static extern byte mraa_i2c_read_byte(IntPtr device);

        [DllImport("libmraa.so")]
        private static extern MRAA.Result mraa_i2c_write(IntPtr device, byte[] data, int length);

        [DllImport("libmraa.so")]
        private static extern MRAA.Result mraa_i2c_write_byte(IntPtr device, byte value);
        #endregion
    }

    public class MRAA
    {
        #region Enumerators
        public enum Result : int
        {
            Success = 0, FeatureNotImplemented = 1,
            FeatureNotSupported = 2, InvalidVerbosityLevel = 3,
            InvalidParameter = 4, InvalidHandle = 5,
            NoResources = 6, InvalidResource = 7,
            InvalidQueueType = 8, NoDataAvaliable = 9,
            InvalidPlatform = 10, PlatformNotInitialized = 11,
            PlatformAlreadyInitialized = 12, ErrorUnspecified = 99
        }
        public enum Platform : int
        {
            IntelGalileoGen1 = 0, IntelGalileoGen2 = 1, IntelEdisonFabC = 2,
            IntelDE3815 = 3, IntelMinnowBoardMax = 4, RaspberryPi = 5,
            BeagleBone = 6, Banana = 7, Unknown
        }
        #endregion

        #region Accessors
        public static string PlatformName
        {
            get
            {
                return Marshal.PtrToStringAuto(mraa_get_platform_name());
            }
        }
        public static string Version
        {
            get
            {
                return Marshal.PtrToStringAuto(mraa_get_version());
            }
        }
        public static Platform PlatformType
        {
            get
            {
                return mraa_get_platform_type();
            }
        }
        #endregion

        #region Constructors and Initialization
        /// <summary>
        /// Initialize MRAA library
        /// </summary>
        /// <returns>Success on first initialization, 
        /// PlatformAlreadyInitialized if MRAA 
        /// has been initialized previously</returns>
        public static Result Initialize()
        {
            return mraa_init();
        }
        #endregion

        #region Deinitialization
        /// <summary>
        /// MRAA documentation states that it is not nessesary to call this function normally 
        /// unless you intend to dynamically unload this library.
        /// </summary>
        public static void Deinitialize()
        {
            mraa_deinit();
        }
        #endregion

        #region External Functions
        [DllImport("libmraa.so")]
        private static extern Result mraa_init();

        [DllImport("libmraa.so")]
        private static extern void mraa_deinit();

        [DllImport("libmraa.so")]
        private static extern IntPtr mraa_get_platform_name();

        [DllImport("libmraa.so")]
        private static extern IntPtr mraa_get_version();

        [DllImport("libmraa.so")]
        private static extern Platform mraa_get_platform_type();
        #endregion
    }

    public class MRAAException : Exception
    {
        private MRAA.Result reason;

        public MRAAException(MRAA.Result reason)
        {
            this.reason = reason;
        }

        public override string Message
        {
            get
            {
                return "MRAA Exception:" + this.reason.ToString();
            }
        }
    }
}