G400 Failed to Perform I2C transaction

Rather than continue on the CP7 thread, I though I would start a new one.

I am seeing a lot of execute failures on the G400 and I hooked up my logic analyser to the I2C bus and I spotted why it fails. At least this seems to be the reason.

In the attached image you will see that the G400 sent a start bit and then the address and read/write bit. This should have been ack’ed by the device but instead it was nack’ed meaning that no device responded to the address.

Looking at the SCL line you can see why. The clock is not correct. The timing goes out at bit 4.

The second image shows a partially completed bus cycle. It’s as if the I2C driver just stops. On both of these, the execute function returns 0.

To show that it does work, the 3rd image is a complete ADC read of 5 bytes.

Just to add to this. I managed to capture a second glitch with the SCL timing.

This time the analyser was unable to decode the byte.

@ Dave McLaughlin -

Hello,

That because it is related to “clock stretching between 7 inch Display and G400”
Try with our workaround on this link: https://www.ghielectronics.com/community/forum/topic?id=14449&page=3

That fix is not working for me. I am still getting failures on the second try.

I am sampling 4 ADC’s, each with 4 channels so I have high I2C bus activity. This worked fine on the ChipworkX albeit, with a 4.3" LCD. It looks like I need to go back to using the 4.3" LCD for this project which is not ideal as the new 5" is high brightness and much better and is now the preferred display for the client. :frowning:

As you have identified this as an issue, is there going to be a fix for this in the next SDK? Is it actually possible to fix this in the firmware?

My design is up in the air just now to using the G400 because of this issue so I am hoping there is a fix for this?

@ Dave McLaughlin -

it is better to give us a simple code and tell us how to reproduce it quickly.

And, I remember there is still softwareI2C, it is quite easy.

I understand about the sample code, but you don’t have the display I am using so no timing or I2C to communicate with? I’ve not sent out the Gadgeteer version yet for getting a PCB made.

Saying that, the CP7 timing is pretty close to this 5" display so it may work but the code is different.

How much slower is software I2C compared to the hardware I2C?

Hey Dat,

I changed the code to use the software I2C and now I have working ADC and capacitive touch and there doesn’t seem to be any issue with the speed either. I am still seeing as fast an update as I saw with the ChipworkX so in effect, it’s as good as before.

Woohoo…

Now all I need to get working is the PD2 pin and see if GPRS works and I am fully happy.

@ Dave McLaughlin -

[quote]
How much slower is software I2C compared to the hardware I2C?[/quote]

if remember correctly, is is now about 300~370Kbs, not slower than hardware I2C too much.

And the speed was higher than 500Kbs, we had to make it slower than 400Kbs to be compatible with common I2C slave devices. So don’t worry about the speed on G400.

Cheers Dat. It’s actually updating the 16 analog inputs much faster than the old ChipworkX anyway and the touch is working perfectly too.

This fix and the new display I am using has given GHI and NETMF a new boost. Glad I purchased a few G400D modules at Christmas time now. :slight_smile:

I support a firmware for a G400S that still runs .NETMF, can anyone relink the workaround referenced here?

The post in question said to replace the ReadRegister function in the DisplayCP7 driver with the below version. It was for NETMF 4.2 only though.

static byte ReadRegister(byte Address)
        {
			int timeout=0x10;
            I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[2];

            // create write buffer (we need one byte)
            byte[] RegisterAddress = new byte[1] { Address };
            xActions[0] = I2CDevice.CreateWriteTransaction(RegisterAddress);
            // create read buffer to read the register
            byte[] RegisterValue = new byte[1];
            xActions[1] = I2CDevice.CreateReadTransaction(RegisterValue);
			while(timeout>0)
			{
				if (i2cBus.Execute(xActions, 100) == 0)
				{
					//Debug.Print("Failed to perform I2C transaction");
					Thread.sleep(10);
					timeout--;
				}
				else
				{
					//Debug.Print("Register value: " + RegisterValue[0].ToString());
					timeout = 0;
				}
				
				
			}
            return RegisterValue[0];
        }