How do i test an I2C interface…i have my fez cobra 2 connected to a MCP23017 chip using i2c…how do i test this interface. This code is failing…
//create I2C object
//note that the netmf i2cdevice configuration requires a 7-bit address! It set the 8th R/W bit automatically.
I2CDevice.Configuration con =
new I2CDevice.Configuration(0x38, 400);
I2CDevice MyI2C = new I2CDevice(con);
// Create transactions
// We need 2 in this example, we are reading from the device
// First transaction is writing the "read command"
// Second transaction is reading the data
I2CDevice.I2CTransaction[] xActions =
new I2CDevice.I2CTransaction[2];
// create write buffer (we need one byte)
byte[] RegisterNum = new byte[1] { 2 };
xActions[0] = I2CDevice.CreateWriteTransaction(RegisterNum);
// create read buffer to read the register
byte[] RegisterValue = new byte[1];
xActions[1] = I2CDevice.CreateReadTransaction(RegisterValue);
// Now we access the I2C bus using a timeout of one second
// if the execute command returns zero, the transaction failed (this
// is a good check to make sure that you are communicating with the device correctly
// and dont have a wiring issue or other problem with the I2C device)
if (MyI2C.Execute(xActions, 1000) == 0)
{
Debug.Print("Failed to perform I2C transaction"); //reaches here
}
else
{
Debug.Print("Register value: " + RegisterValue[0].ToString());
}
}
}
}
The address of this device is not 0x38. From section 1.4 of the datasheet, the address is 0100xxx where the three unknowns are based on the address line settings. Assuming they’re all pulled to GND, that will be 0100000, or 0x20.
So it’d be great if you can tell us, is 42 decimal or hex (or octal, but that’s not likely )
If you’re seeing an 0x42, or 42 decimal, still doesn’t make sense to me. Can I ask have you checked your pull up resistors?
So I’m assuming you’re using a logic analyser and are checking the CLK line at the same time yeah? You should see a start bit (SDA transition high to lo with SCL high) then followed by the start of the CLK toggling - you should get an 01000010 (assuming a WRITE operation). I’ll dig out a device and the logic analyser and check what I get.
Actually, 0x42 is the full control byte that implies you’re doing a write. You’ll see 0x43 if you issue a read first.
I have a working repro of this now with my LA. Here’s the code I used
public static void Main()
{
I2CDevice i2c = null;
I2CDevice.I2CTransaction[] writeTrans = new I2CDevice.I2CTransaction[1];
I2CDevice.I2CTransaction[] readTrans = new I2CDevice.I2CTransaction[2];
OutputPort resetPin = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di8,false);
OutputPort led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, false);
byte[] singleCommand = new byte[1];
byte[] writeBuffer = new byte[2];
byte[] readBuffer = new byte[1];
int retval;
I2CDevice.Configuration config = new I2CDevice.Configuration(0x21, 400);
i2c = new I2CDevice(config);
writeBuffer[0] = 0x00;
writeBuffer[1] = 0xff;
writeTrans[0] = I2CDevice.CreateWriteTransaction(writeBuffer);
while (true)
{
Thread.Sleep(2000);
resetPin.Write(true); // toggle my trigger pin!
led.Write(true);
retval = i2c.Execute(writeTrans, 100);
resetPin.Write(false); // toggle my trigger pin!
led.Write(false);
Debug.Print("Returned: " + retval);
}
// Thread.Sleep(Timeout.Infinite);
}
As you can see I just loop through this with a 2sec pause between writes. My Writes are meant to write the IO Direction register to 0xff (this is the first step of the initialisation routine, based on the codeshare code Architect pointed out earlier). I toggle the LED and a trigger pin that I’m using to trigger the LA at the start of the loop, then clear them at the end.
When I decode the I2C data I can see I don’t get an ACK, which is expected since I don’t have the device.
So now I reckon I’d be checking the device pins you have wired correctly (SDA and SCL), and potentially check the RESET pin of the chip to make sure that’s connected in accordance with the datasheet. You’ve never told us if you’re using a commercial breakout board, so if it’s a homemade thing I’d be checking the soldering for dry/missed joints.