Software I2C

So i hooked up the new module and tried using the Software I2C driver at for the first time and it basically worked as expected :slight_smile:

So now the dumb questions… :smiley:

 int count = _i2C.Receive(true, false);
            if (count == 0)
                _i2C.Receive(true, true);
                if (count < 16 && count > 0)
                    byte[] buffer = new byte[count + 2];
                    for (int j = 0; j < count; j++)
                        buffer[j] = _i2C.Receive(true, false); 
                    _i2C.Receive(true, true);
                    string serial = "";
                    for (int j = 0; j < buffer.Length; j++)
                        serial += buffer[j] + " ";


is _i2C.Receive(true, false); ACK and NACK?

Datasheet for the moduels states - i2c_read(0); Read with NAK before stop is that _i2C.Receive(true, true); ??

So nicking this from io60p16

public byte ReadRegister(byte reg)
            byte[] data = new byte[1];
            // Bring the pointer to the needed address
            int send = i2c.Write(DEV_ADDR, new byte[] { reg });
            // Read the address
            i2c.Read(DEV_ADDR, data);
            return data[0];

How do you do Nack with Gagdeteer Software I2C?

Dazed and Confused!

You can’t. And I suggest you use the built it native version in our libs.

The drivers are high level. They handle everything internally. You can’t control start, stop or even nacks.

@ Gus - so does that mean an I socket or can we nack with the software library using X socket?

Protocol handles all that for you. You don’t need to worry about it. The only issue is that SoftwareI2C is slow. Which can be ok for some devices, but not for others.

Last question then which is faster - better?

GHI.OSHW.Hardware.SoftwareI2CBus or SoftwareI2C from codeshare?

Guess i just need to test and see the differences…

Should be comparable. But I would use GHI.OSHW.Hardware.SoftwareI2CBus it is already there - will keep your code smaller.

1 Like

@ Architect - Cheers fella

Actually the one built in is done is C++, not C#. My guess that it is 100 times faster!

Yes you right! For some reason I was thinking about Gadgeteer DaisyLink implementation of the I2C in 4.1 (case when socket is not an I2C socket)

Even then, the mainboard drivers overrides the built in C# ones with our native ones :slight_smile: The managed ones from gadgeteer core are never used on our products. Yeah we are cool like that lol, just kidding.

Daisylink is “virtual”, fast and chainable…and runs on all sockets!

That is new. As far as I remeber, DL was implemented in Gadgeteer and should be Mainboard independent, must be intefaced out now in 4.2.

I have to go over Gadgeteer changes in 4.2. (note to myself)

Yes but this was one of our suggestions to the core team. DL is still from core but the core uses built in slow I2C by default or a manufacture can override with faster native implementation. We do this even on open source boards :slight_smile:

@ justin - I’ve used the built-in with RFID and it is fast enough:) It’s currently connected to socket I. I’ll try to share some code during the weekend. My client didn’t give me permission to publish it. So I have to write some new.

@ Patrick - funny you should mention…

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using RfidTest;

namespace MFConsoleApplication1
    public class Program
        private static Microsoft.SPOT.Hardware.InterruptPort _interruptPort;
        private static SoftwareI2C _sI2C;

        public static void Main()
           _sI2C = new SoftwareI2C(GHI.OSHW.Hardware.FEZCerbuino.Pin.Digital.D0, GHI.OSHW.Hardware.FEZCerbuino.Pin.Digital.D1,100);
            _interruptPort = new InterruptPort(GHI.OSHW.Hardware.FEZCerbuino.Pin.Digital.D7, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            _interruptPort.OnInterrupt += new NativeEventHandler(interruptPort_OnInterrupt);
        static void interruptPort_OnInterrupt(uint data1, uint data2, DateTime time)
            byte[] buffer = new byte[20];
            _sI2C.Transmit(true, false, 0x84);
            _sI2C.Transmit(false, false, 0x01);
            _sI2C.Transmit(false, false, 0x83);
            _sI2C.Transmit(false, true, 0x84);
            _sI2C.Transmit(true, false, 0x85);
            int count = _sI2C.Receive(true, false);
            buffer[0] = (byte)count;
            for (int i = 0; i <= count; i++)
                buffer[i + 1] = _sI2C.Receive(true, false);
            buffer[count + 2] = _sI2C.Receive(false, true);
            string key = "";
            foreach (var b in buffer)
                key += b.ToString() + " ";
        private static void Reset()
            _sI2C.Transmit(true, false, 0x84);
            _sI2C.Transmit(false, false, 0x01);
            _sI2C.Transmit(false, false, 0x80);
            _sI2C.Transmit(false, true, 0x81);

Output is 6 131 2 81 132 105 168 113
Which is a 1k card with a serial of A8698451

Nice, is this based on the sm130?

Yup :slight_smile:

You got it all hooked up and got it working. That’s great…

Are you doing this as part of your job?

@ Patrick - Day job is print software for production Xerox printers - this is play/enjoyment :slight_smile:
The I2C wasn’t as scary as i thought it was going to be…
Board design will be off to OSHPark tonight.

@ justin no, I2C isn’t scary at all! The documentation is a bit scary at first but when you get started, especialy with gadgeteer stuff, it becomes as clear as crystal. To get I2C hardware going can be a pain in the ass. But once you get that running it is no rocket science anymore :slight_smile:

I’m looking forward to your boards.