IO60P16 Module driver discussion thread (Contributors)

Just for info, now the code is running fine with built-in SoftwareI2C (under Gadgeteer.DaisyLink namespace), and I can confirm that is 100% working on the Cerberus with 4.2 MF (QFE1) + gadgeteer 2.42.600. The code is exactly the same I run on hydra 4.1 with exactly the same hardware setup for IO64P16 board.

@ ian: I read back register without problems also in 4.2. Checking 4.2 software I2C signals, it seems they are consistent as in 4.1

Nice job, Dobova. But this is very frustrating. Iā€™ve tried tonight with Hydra & Cerberus & several different sockets on both and I still canā€™t get a read to work. Would you mind emailing me your complete solution (driver & test project) just so I know for certain that nothing is different.

I had an Open Bench Logic Sniffer sitting in my mailbox when I got back home today :slight_smile: Hopefully, Iā€™ll figure out how to use it quickly and can gather some real evidence about my problem.

I will update later, I spent 3 h yesterday and you are right about i2c problems on reading transactions

Interesting. Iā€™m curious to hear what youā€™ve now learned.

Hi Ian, I were not convinced about my result ā€¦ too easy. And I canā€™t believe you got so different result. Just to get worst cerberus with this 4.2 release is a mess, due to continue USB lockup and deploy problems. So I switched to Hydra that is little more realiable on both release.
In any case cerberus has same results.
The problem you face is that when you read register n from the chip, always read input register of port 0 in 4.2. So Iā€™ve atteched the protocol analyzer, and you can see in attached image. Iā€™ve connected 4 wire between P0 and P1. P0 set output a value from 0 to F and P1 reading input port 1 (reg 1h) back I must get same value. The value got from input reg 1h I then output to port 3 where leds light. I worked fine, but just becouse the ports are equal, so I was outputting P0 val and not P1. Ok, I added a pullup wire to keep bit 7 of port 1 to high. So reading P0 i must read a val from 0ā€¦F and reading P1 I must get a val 80ā€¦8F. Obviously when I saw the same value 0ā€¦F on both ports, I realize that Iā€™m reading back just input port 0 reg always, damned me!. This not happens on 4.1 but works perfectly. I discovered also that interrupt works fine in 4.1 and in 4.2 no way.
Back to I2C that seems to be the main cause of the issue found. In fact using the mutliport reading feature I got it working in 4.2, just reading back 8 adiacent registers, from reg 0 to erg 7


        public byte[] ReadMultiRegisters(byte startreg)
        {
            byte[] data = new byte[8]; // { reg, value };
            int send = i2c.Write(DEV_ADDR, new byte[] { startreg });
            i2c.Read(DEV_ADDR, data);
            return data;
        }

The story is not ended becouse I found the i2c soft protocols absolutely equal in 4.1 and in 4.2 ā€¦ stil checking ā€¦
Look at attached images for 4.1 and 4.2 packet disassembly. See also in 4.1 the interrupt (yellow line) going up and resetting to low from event and in 4.2 always high

Just for completeness this is image for multiregister read in 4.2. (the 7bit of P1 wasnā€™t in pullup). You can see that I read back different value from the 8 regs, as expected.
An other difference I noted is that the SCL clock is veeery slow on 4.2, riching 130us per pulse, meanwhile on 4.1 it is 5us ā€¦ why ?

There is not allowed to be a STOP in the message when reading a register. It must be START(WRITE), RESTART(READ), STOP.

Thus that code must be changed from a write + read to a writeread command. Or if using hardware I2C then it must be changed to one transaction containing a write and a readā€¦

I suspect weā€™re back to what GMod has suggested. I donā€™t think I noticed it earlier but there actually is a WriteRead() for SoftwareI2C. Have you tried it? I seem to have done something to corrupt my project and canā€™t get it to run anything at the moment. Iā€™ll try again tonight. You might try changing ReadRegister() to thisā€¦


public byte ReadRegister(byte reg)
        {
            byte[] data = new byte[1];
            i2c.WriteRead(DEV_ADDR, new byte[] {reg}, data);
            return data[0];
        }

No ideaā€¦but it is troubling. Thereā€™s not a clock setting for SoftwareI2C that Iā€™ve seen but it seems that one is getting applied somewhere.

The funky err(?) I get when I try to run now pops up in a new window. Nothing out of the usual shows up in the Output window. Anyone seen this before?

@ Errol
I know about that, the i2c is the software I2C built in gadgeteer, not hardware i2c. If I use WriteRead the things go weird:


Port 1:255 - Read back Port 0:0
Port 1:255 - Read back Port 0:0
Port 1:255 - Read back Port 0:0
Port 1:255 - Read back Port 0:0
Port 1:5 - Read back Port 0:0
Port 1:6 - Read back Port 0:0
Port 1:7 - Read back Port 0:0
Port 1:8 - Read back Port 0:0
Port 1:9 - Read back Port 0:0
Port 1:10 - Read back Port 0:0
Port 1:11 - Read back Port 0:0
Port 1:12 - Read back Port 0:0
Port 1:255 - Read back Port 0:0
Port 1:255 - Read back Port 0:0
Port 1:255 - Read back Port 

as you can see I miss lot of reading command from register

@ Ian ā€¦ Iā€™ve no idea ā€¦ good crash in any case

@ dobova,
What does your logic analyser show?

As far as I know the software writeread is broken anyway in that it doesnā€™t send a restart but does a whole new Start/Stop session. But it should still work the same as seperate write and read commandsā€¦

@ Errol
All the images are made with separate write/read. The analyzer just show the i2c transactions it sees on the wires ā€¦
The image attached show whatā€™s happen with ā€œWriteReadā€ transaction.

PS: Obvously using hardware I2C everything works fine in 4.1 and 4.2 with no issue at all.

In the bottom listing where is shows all the data, it doesnā€™t show START or STOP events. Can that be enabled?

@ Errol, each line is a start-stop or start-restart condition. It seems you cant visually do more.
Iā€™ve tried:

  1. dual transaction, Write then Read
  2. single transaction WriteRead
  3. ReadRegister that is equal to WriteRead.
    No way.

Becouse everything is fine with hardware I2C, the software driver is bugged. If Iā€™ve time this evening I will look inside source code of SoftwareI2C.cs.

Whatā€™s the meaning of this cool line:

            
GTI.SoftwareI2C.ForceManagedSoftwareI2CImplementation = true/false;

I see that works better the managed (setting true) driver although very slow.

@ Ian,
are you thinking to continue the development of this driver (I hope so) ? Could be good idea to set up a codeplex ā€¦ waiting new 4.2 ā€¦

Absolutely! Not planning to stop until itā€™s done. I spent Monday and Tuesday learning to use my new logic analyzer and working through some bugs in itā€™s softwareā€¦ Last night I decided to reflash a Hydra back to 4.1 since you said itā€™s working there and will continue the driver development under 4.1 so that it gets done. Maybe the upcoming 4.2 release will solve our problems with 4.2. If not, then that will be the next thing to tackle once there is at least a working driver available.

I posted a link earlier in this thread (#48) to the area in CodePlex where Iā€™m keeping the code for now. Once we get a v1.0 finished then it will get moved under GHIā€™s module section of the main Gadgeteer CodePlex project. If you want me to set you up as a contributor at the current area, thatā€™s not a problem. I have some other stuff out there but itā€™s separated and nothing to worry about.

Have you had a chance to dig any more into the SoftwareI2C bits and see what could be the issue?

@ ianlee74 -

I will do ā€¦ as soon I have news, I will update here.

This is a summary of the status about IO64P16 tests, becouse I got a lot of confusion.
The board used is Hydra (1 with 4.2 fw, 1 with 4.1 fw). Cerberus is 4.2 fw, but too many lockups for using it and the few tests done show that the behaviour is absolutely equal to Hydra 4.2.

4.1:

  • It works great with hardware I2C.
  • It works fine using Gadgeteer.Interfaces.SoftwareI2C class setting (default)
             SoftwareI2C.ForceManagedSoftwareI2CImplementation = false;

  • It doesnā€™t work using Gadgeteer.Interfaces.SoftwareI2C class setting
             SoftwareI2C.ForceManagedSoftwareI2CImplementation = true;

  • Interrupt setup correctly and reset correctly

4.2

  • It works great with hardware I2C.
  • It doesnā€™t work with software I2C. (gadgeteer.daisylink) For some reason, 4.2 doesnā€™t use native software I2C ignoring
SoftwareI2C.ForceManagedSoftwareI2CImplementation = true/false

.

In the attached image you can see very different behaviour between 4.1 native sw I2C (up tracks and working) and managed software I2C (down tracks). When getting signals as in showed in down image traces the CYP9560 reset internal logic to register 00h, so you can read from reg 0 (write to reg 0 also but no meaning), that is port 0 and nothing more. Looking at SoftwareI2C class src, Iā€™ve not found the bug.

Are others experiencing a large number of softwarei2c exceptions stemming from quick sequential read write commands to this module. I have a simple bit of code that issues make pin high and make pin low commands to this module in quick succession. At random iterations through the loop i will get a softwarei2c exception. Im using no timers or thread.sleeps in my code. Ive noticed if i include thread sleeps amounting to about a second between commands the problem goes away. Im hoping this is an issue with software i2c as the application i planned on using this module for is going to need much higher execution times between read and write commands. I can post code later if needed im running on a hydra with fw 4.1.

@ CSharpie -
I didnā€™t get any exception in the software i2c code, I use no timer, but program run in a thread. But no success, I can write to registers, but canā€™t read, except if I read 8 regs in one call but not always works. Iā€™m stuck nowā€¦ I will see.
The logic inside the code of the i2c driver seems ok but may be that there are some timing problems. In the meanwhile Ianlee is writing a great high level driver!
In any case if you stai with 4.1 and an Hydra board you have native softwarei2c that works very fine.
If you want to debug the sw-i2c in 4.2, just download from gadgeteer on the codeplex the file [em]SoftwareI2C.cs[/em] (branch [em]GadgeteerCore\Libraries\Core\DaisyLink42[/em]) and include in your project, removing reference to [em]Gadgeteer.DaisyLink[/em].

Thanks dobova ill look into moving my code into a seperate thread from ProgramStart and see if that fixes the problem. I noticed in MakePinHigh and MakePinLow the first line of code is readport so maybe im getting some of these random read errors that are leaving the module in a dirty state for the next read or write command that gets issued. Itā€™s a strange error as it will work for a seemingly random number of iterations and then fail. Hopefully we can get these issues worked out as id like to use this module.