Hi! I’ve got a problem with the I2C read transaction.
When I try to write and read from the 24LC512 EEPROM I’ve got no problem, and I can write and read all the data I want, but if I try to read from a AnalogDevices SigmaDSP, I get in troumble.
The main problem is that when I a read transaction with the command:
The transaction stops…and when there is used the Read Address (my device address + 1)… my device doesn’t reply, because it thinks that the i2c transaction is ended. In the figure it is showed the LogicAnalyser transaction Analysis made on the bus…
My device needs (I know this by the datasheet) this kind of the read sequence:
START
CHIP ADDRESS (0X68)
ACK BY SLAVE
SUB ADDRESS HIGH
ACK BY SLAVE
SUB ADDRESS LOW
ACK BY SLAVE
START (HERE I GET THE WRONG STOP CONDITION I SHOULD CHANGE!!!)
CHIP ADDRESS READ (0X69)
DATA BYTE 1
ACK BY MASTER
(OPTIONALLY SOME MORE DATA BYTE AND ACK BY MASTER…)
STOP CONDITION
So, is there a way to force the FEZPanda to DO NOT create the STOP condition and continue with a Start Condition, as my needs?
I think the Data sheet has a typo… If the device requires a start condition on the read transaction… stands to reason that a stop should have been sent before hand. You can always use the SPI instead if you’re struggling!
Oh, yes…the SPI for me is a much better (and simpler) protocol…but to use it on my device I should make a new boards for the ADAU1701, since I’ve got an evaluation board that don’t permits to use the SPI >:(
Sorry, but…what do you mean for “stands to reason that a stop should have been sent before hand”???
here it is:
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;
namespace FEZPandaEEPROMI2C_withDSPclass
{
public class Program
{
/*static i2c_eeprom MyEEprom = new i2c_eeprom(0xA0, 400);*/
static i2c_adau1701 ad1701I2C = new i2c_adau1701(0xa0, 100);
public static void Main()
{
int i = 0;
// Blink board LED
bool ledState = false;
OutputPort led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, ledState);
i = 0;
for (i = 0; i < myDsp.program_data.Length; i++)
{
ad1701I2C.Write(i, myDsp.program_data[i]);
Debug.Print("written " + myDsp.program_data[i].ToString() + " @ address " + i.ToString());
ledState = !ledState;
led.Write(ledState);
}
for (i = 0; i < myDsp.program_data.Length; i++)
{
Debug.Print("read " + ad1701I2C.Read(i).ToString() + " @ address " + i.ToString());
ledState = !ledState;
led.Write(ledState);
}
and the Write and read methods are:
public void Write(int Register, byte data)
{
var xActions = new I2CDevice.I2CTransaction[1];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Register >> 8), (byte)(Register & 0xFF), data });
I2C.Execute(xActions, 1000);
Thread.Sleep(5); // Mandatory after each Write transaction !!!
}
public byte Read(int Address)
{
var Data = new byte[1];
var xActions = new I2CDevice.I2CTransaction[1];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF) });
I2C.Execute(xActions, 1000);
Thread.Sleep(5); // Mandatory after each Write transaction !!!
xActions[0] = I2CDevice.CreateReadTransaction(Data);
I2C.Execute(xActions, 1000);
return Data[0];
}
public byte ReadOneByte(int Address)
{
var Data = new byte[1];
var xActions = new I2CDevice.I2CTransaction[2];
xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF) });
/*
* I2C.Execute(xActions, 1000);
* Thread.Sleep(5); // Mandatory after each Write transaction !!!
*/
xActions[1] = I2CDevice.CreateReadTransaction(Data);
I2C.Execute(xActions, 3000);
Thread.Sleep(5);
return Data[0];
}
I have removed the “I2C.Execute(xActions, 1000);” so I have no more Stop condiction…but I 've got another problem!!!
If I use a Slave address of “0xA0” (the EEPROM on the circuit) I can use this new method and it does works well…but if I use the ADAU1701 slave address, 0x68, I can see that the device reply well on the write transaction, but the read device address (that should be 0x69… 0x68+1) becomes 0xE9…
In binary notation I have:
0b11101001, but I should have 0b01101001… what could it be???
[quote]- ack… why do I get an ACK here as there are no devices with this address???
[/quote]
What if you use some other address? do you get an ACK back?
If I use the EEPROM Address yes… but if I use some others address, the process stops with a NACK in the write sequence (the first after the start sequence) since there is no device responding…
I don’t like the way the address handling is coded in the i2c sample; I had a quick look recently but didn’t battle through to conclusion.
You might find you need to explicitly use a 7-bit address, and you are currently using an address that is out of that range. Use the BASE 7-bit address and let the code move it to 8-bit with 0/1 for the read or write as appropriate.
I personally am thinking I’ll make that explicit in my code when I get back to it - only use the 7-bit address, check it’s not out of range, and then the headache should be reduced.
Sorry Brett, I think I didn’t understood your reply…
I’m not using a 10 bit address… I have 2 devices in the I2C line, but I use only 1 of them in my code:
I’ve got a EEPROM that uses the 0xA0 address to write, and 0xA1 to read…and it works very well;
I’ve got a SigmaDSP ADAU1701 device, that uses the 0x68 address to write (that seems to work well…as the ACK by device are correct), and uses the 0x69 address to read transactions.
The FEZ seems to write well to my ADAU1701 device…but with my logic analyzer it seems to use the 0xE9 address…
It is in binary:11101001 and not 01101001…
I think it could be a timing problem of my logic analyzer, since the ADAU1701 reply with a ACK…but I can’t anyway read the datas I have got written in the internal memory
It is a very strange problem…
I have got a SigmaDSP programmer (USBi) and it could comunicate well with my ADAU1701 device with the 0x68 address (and 0x69 for reading value…), but I can’t read the signals due to too much speed of the programmer…
Sorry, let me try to explain. The key is making sure that you’re talking about i2c addresses correctly.
Technically I2C addresses are 7-bits only. You’ve referred to them with 8 bit addresses, which are the valid addresses for your devices (assuming all address pins are taken to GND). The TRUE ADDRESS that anyone reading a data sheet would interpret is a 7-bit address and then the R/W bit; even the netmf real I2C call I2CDevice.Configuration takes a 7-bit address. So I personally would suggest that your constructor takes a 7-bit address and you only refer to devices by their 7-bit address, not the 8-bit read or write address. That is how I intend to have my constructor.
What I initially suspected might have happened is you simply read an address from the data sheet that gave you the 7-bit address while your constructor takes an 8-bit address; I’ve checked the data sheets and don’t believe that is the case (but assume still that you have all address pins tied to GND).
So what seems strange to me is that you have two different I2C devices that each appear to work, but on different devices. That to me makes me think that the LA bits are a mis-read as Gus says, but the 1001 seems to coincidental to be wrong. And why aren’t you
So the only thing I can suggest at this point is stepping back and creating a test app just to make simple reads and writes to your device to prove it does or doesn’t work; make sure you check return codes fully etc. I’d work from a simple starting point that has nothing fancy just code in main() and see whether that works?
I have done some measures with a professional equipment of a friend of mine, and I saw a lot of noise in the transactions with the official programmer, and a frequency of 83kHz I2C clock.
Anyway I finally get the things working using a self-booting system for the DSP, and using the FEZ Panda to “command” the DSP to change its own parameters, and it works very well!
Now I’m integrating all the stuffs in a C# class to have all the commands coded…or something similar.
The reading transactions doesn’t works, but I have to inspect some more with a pro equipment to know what is going on… but I think the wrong read address is a logic analyzer error, I’m almost sure of this.
Now I’m getting working on the SD-CARD interface, to have access to a FAT16 partition, and read some files…but it is another stuff (but the same project)