How to use i2C driver in C# ??

Msallati
Hi , 

I am not very familiar with WINCE and so I hope u can help me .. 

is it possible for the C# application to communicate (through I2C.dll) with
any device supporting I2C interface connected to the mini2440 ??

is there any (C#) sample code to do that ?? 

i know that is possible under "C" ,

like the code in the link
http://www.domodom.fr/spip/Utiliser-le-driver-I2C-dans-une.html?lang=en

but what about C# ?????


Hope u can help me ...
Msallati..

Cabrito
I had the same problem and I made this solution:

With visual studio, I created a MFC DLL smart device app in C++, a static
DLL. I inserted this C++ code and call this DLL in C# with DllImport
function.
My program runs, but I dont know how to run i2c better and made my own
application.

Msallati
Thank u so much for this solution!! I am going to try it now :)

thantzinaung
I can not write i2c read/write function .so could you send for me i2c c#
code

regardly sir

domodom
Hello, 
My GPIO driver uses the same driver model that the i2c driver. You can find
on my website a c# sample of use of this driver, maybe it will help you...
Domodom

bpapineau
Hi,

I have a solution. Please note that I do not print value on any control
form.

Here's the code:

/*
********************************************************************************
**********
 * Author:  Benoit Papineau
 * Date:    27.04.2011
 * 
 * Description: Basic code to read and write on the Eeprom of the Mini2440
 *******************************************************************************
*************/
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;
// compile with: /unsafe
namespace TestI2C
{
    public partial class Form1 : Form
    {
        //Invoke methods
        [DllImport("coredll.dll", EntryPoint = "DeviceIoControl",
SetLastError = true)]
        internal static extern int DeviceIoControlCE(int hDevice, int
dwIoControlCode, byte[] lpInBuffer, int nInBufferSize, byte[] lpOutBuffer,
int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped);

        [DllImport("coredll", SetLastError = true)]
        private static extern IntPtr CreateFile(string lpFileName, uint
dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint
dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImport("coredll.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        //Found on pinvoke.net
        public const UInt32 GENERIC_ALL = 0x10000000;
        public const UInt32 GENERIC_READ = 0x80000000;
        public const UInt32 GENERIC_WRITE = 0x40000000;
        public const UInt32 GENERIC_EXECUTE = 0x20000000;
        public const UInt32 FILE_SHARE_READ = 1;
        public const UInt32 FILE_SHARE_WRITE = 2;
        public const UInt32 OPEN_EXISTING = 3;
                
        //Found with I2C driver
        public const Int32 IOCTL_I2C_READ = 262144;
        public const Int32 IOCTL_I2C_WRITE = 262148;
        public const Int32 IOCTL_I2C_GET_FASTCALL = 262152;

        /// <summary>
        /// Struct for I2C driver
        /// </summary>
        unsafe struct _I2C_IO_DESC {
            public UInt32 SlaveAddr;        // Target Slave Address
            public byte WordAddr;           // Starting Slave Word Address
            public byte* Data;              // pBuffer
            public UInt32 Count;            // nBytes to read/write
        }

        /// <summary>
        /// I2C Handler
        /// </summary>
        private static IntPtr _i2cFile;

        //Migth be useless
        int _rCount = 0;

        public Form1()
        {
            InitializeComponent();                        
        }

        private void OpenHandle0()
        {
            //Open the channel 0
            _i2cFile =
                CreateFile
                    ("I2C0:",
                    GENERIC_READ | GENERIC_WRITE,
                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                    IntPtr.Zero,
                    OPEN_EXISTING,
                    0,
                    IntPtr.Zero
                    );  
        }

        private void CloseHandle0()
        {
            CloseHandle(_i2cFile);
        }

        private void bttnRead_Click(object sender, EventArgs e)
        {
            unsafe
            {
                byte[] data = new byte[16];
         
                fixed (byte* p = data) //Make sure that garbage collector
won't move the data 
                {
                    _I2C_IO_DESC i2cMsg;
                    i2cMsg.SlaveAddr = 0xA1;    //Eeprom Adress
                    i2cMsg.WordAddr = 0;        //Start Adress
                    i2cMsg.Count = 16;          //Nb of byte to read
                    i2cMsg.Data = p;            //Pointer

                    byte[] buffer = ObjectToByteArray(i2cMsg);
                    OpenHandle0();
                    DeviceIoControlCE((int)_i2cFile, IOCTL_I2C_READ,
buffer, buffer.Length, buffer, 0, ref _rCount, IntPtr.Zero);
                    CloseHandle0();
                    _I2C_IO_DESC i2cRead =
ByteArrayToObject<_I2C_IO_DESC>(buffer);

                    //*****At this point, "data" contains the content of
the eeprom*****
                }
            }
        }

        private void bttnWrite_Click(object sender, EventArgs e)
        {
            //Some data
            byte[] data = new byte[16];

            data[0] = 48;
            data[1] = 48;
            data[2] = 48;
            data[3] = 48;
            data[4] = 48;
            data[5] = 48;
            data[6] = 48;
            data[7] = 48;
            data[8] = 48;
            data[9] = 48;
            data[10] = 48;
            data[11] = 48;
            data[12] = 48;
            data[13] = 48;
            data[14] = 48;
            data[15] = 48;


            unsafe
            {
                fixed (byte* p = data) //Make sure that garbage collector
won't move the data 
                {
                    _I2C_IO_DESC i2cMsg;
                    i2cMsg.SlaveAddr = 0xA1;    //Eeprom Adress
                    i2cMsg.WordAddr = 0;        //Start Adress
                    i2cMsg.Count = 16;          //Nb of byte to read
                    i2cMsg.Data = p;            //Pointer

                    byte[] buffer = ObjectToByteArray(i2cMsg);
                    OpenHandle0();
                    DeviceIoControlCE((int)_i2cFile, IOCTL_I2C_WRITE,
buffer, buffer.Length, buffer, 0, ref _rCount, IntPtr.Zero);
                    CloseHandle0();

                    //*****At this point, i2cMsg is sent to the eeprom*****
                }
            }
        }

        /// <summary>
        /// Convert an object to a byte array. Will not work with dynamic
size object
        /// This method is based from an example on codeproject.com
(http://www.codeproject.com/KB/cs/C__Poiter.aspx)
        /// </summary>
        /// <param name="obj">Object to convert</param>
        /// <returns>Array of bytes</returns>
        public byte[] ObjectToByteArray(object obj)
        {
            int Length = Marshal.SizeOf(obj);
            byte[] byteArray = new byte[Length];
            IntPtr ptr = Marshal.AllocHGlobal(Length);
            Marshal.StructureToPtr(obj, ptr, false);
            Marshal.Copy(ptr, byteArray, 0, Length);
            Marshal.FreeHGlobal(ptr);
            return byteArray;
        }

        /// <summary>
        /// Convert a byte array to an object of type T. Will not work with
dynamic size object
        /// This method is based from an example on codeproject.com
(http://www.codeproject.com/KB/cs/C__Poiter.aspx)
        /// </summary>
        /// <typeparam name="T">Type of the returned object</typeparam>
        /// <param name="byteArray">Byte array to convert</param>
        /// <returns>Object from byte array</returns>
        public T ByteArrayToObject<T>(byte[] byteArray)
        {
            T obj;
            int Length = Marshal.SizeOf(typeof(T));
            IntPtr ptr = Marshal.AllocHGlobal(Length);
            Marshal.Copy(byteArray, 0, ptr, Length);
            obj = (T)Marshal.PtrToStructure(ptr, typeof(T));
            Marshal.FreeHGlobal(ptr);
            return obj;
        }    
    }
}

usama yaseen
Hi Bpapineau!

1st of all Thanks for the source code, i am trying to use i2c for my ok6410
board (http://arm9board.net/sel/prddetail.aspx?id=354&pid=200) , i need to
ask what parameters do i need to change to use your code,
I changed the lpFileName to prefix of my dll, driver loads perfectly
the DeviceIoControl works returns no error but i am unable to read and
write, the number of bytes returned (lpBytesReturned) is 0. Any clue what
could be the issue ?

Thanks.



regards

usama

Andreja
Thank you Benoit, your code is very helpful! If you're ever in Slovenia I'm
buying you a beer :)

Eric Serrot
To send and read data from Windows and C#, VB.NET IN I2C or SPI,
I found that the www.Nusbio.net device is easier to use because all the
samples are open source in in C# or VB.NET (and they are a lot of them).
The source are implemented in different layer, first how to deal at a high
level with an I2C EEPROM, then with a debugger can drill down
and look into more detail into the I2C protocol.

They support I2C EEPROM, LCD, A lot of the Adafruit I2C Devices.
They support all SPI EEPROM (Faster), of 8x8 or 328x LED Matrix based on
the MAX7219 chip.

It might sabe you time