This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I am using a TMS320F28335 MCU and I have noticed that if I perform consecutive I2C writes, (perhaps r/w and r/r also, I haven't checked yet), that the protocol of the I2C message isn't maintained, namely the second data byte of the first write isn't Acked and as a result no stop bit is generated. I have noticed also that if I introduce about >= 4 sec delay this is resolved, i.e: something resets and I'm good to go again. Is this a problem which has been observed elsewhere, and if so, have there been any patches to the I2C drivers to address this?
Any help would be appreciated.
Thanks
Simon.
Hi,
An update.
I have downloaded the TI sample code. The Example_2833xI2C_eeprom July 30 2009 to be exact.
With a standard I2C bus slave it speaks to it fine.
However, when I try to 'serialise' the code to simulate what I am actually doing in the real system it's behaviour is unreliable and undeterminate.
I wish to perform multiple consecutive read/writes to the same address, therefore my modifications to Example_2833xI2C_eeprom.c, (below), involve effectively commenting out all of the read back functionality and performing 3 writes to the slave address. I added some verification at line 220 to effectively wait for the Busy Bit and the Stop Bit to become unset before the next write. This yielded that 2 of the 3 sent messages were sent correctly. When the program was reloaded the lost third message is the first to come through, followed by the next message, so effectively you lose a message each iteration.
I found that calling function InitPieVectTable in DSP2833xPieVect.c after each write resolved the problem, (well actually I found that updating the 128 registers to PieVectTableInit part of the function actually had the desired affect, below).
So, in summary I have a system that now appears to work, but I don't know why!!
Thanks in advance - code below
Simon.
Example_2833xI2C_eeprom.c
Main:
for(i=0; i<3; i++)
{
I2cMsgOut1.MsgBuffer[2] = i; //Tag byte 2 of payload with ident
if(I2cMsgOut1.MsgStatus == I2C_MSGSTAT_SEND_WITHSTOP) //Irrelevant but left in
{
Error = I2CA_WriteData(&I2cMsgOut1);
if (Error != I2C_SUCCESS)
{
FailCount++;
}
while (I2caRegs.I2CSTR.bit.BB == 1 || I2caRegs.I2CMDR.bit.STP == 1)
{
//Kill some time
}
InitPieVectTable(); //WHY??
}
if (FailCount > 0)
{
FailCount = 0;
}
}
DSP2833x_PieVect.c
InitPieVectTable:
//---------------------------------------------------------------------------
// InitPieVectTable:
//---------------------------------------------------------------------------
// This function initializes the PIE vector table to a known state.
// This function must be executed after boot time.
//
void InitPieVectTable(void)
{
int16 i;
Uint32 *Source = (void *) &PieVectTableInit;
Uint32 *Dest = (void *) &PieVectTable;
EALLOW;
for(i=0; i < 128; i++)
*Dest++ = *Source++;
EDIS;
// Enable the PIE Vector Table
//PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
}
Hi,
I appear to be talking to myself again!
Ok, a bit of an update, I think I am homing in on a sensible question.
Our requirement is to perform multiple I2C access, (read or write), with little latency. Therefore effectively at some points we need to consecutively perform I2C operations in our source code. I have noticed throughout this exercise that I have to throttle our code to allow I2C operations to execute correctly.
I posted some observations earlier this week about calling the InitPieVectTable() function between each successive write. This turned out to be a Red Herring and the real affect of adding this call was the introduction of needed latency into the system. I have noticed that to allow the I2C messaging to be called 'consecutively' I have to introduce a delay of 75 iterations of a loop, (on a 150MHz processor means 0.0000005s, I think - I'm new to CCS4 and used to having the benefit of a OS to use a system clock to give you a definitive value!). However I'm sure we can agree that a null loop introduces latency.
The question is why can't I consecutively perfom any I2C writes without latency?
Either I am exceeding the capable bus speed or I am waiting/polling an incorrect status flag. As I mentioned in this Noddy example I merely wait on the Busy and Stop bits thus:
while (I2caRegs.I2CSTR.bit.BB == 1 || I2caRegs.I2CMDR.bit.STP == 1)
Hi Simon,
Is this happening at low speeds (100 KHz) as well? If your slave device is incapable of operating at the bus frequency of the master it can stretch the clock and that would keep the busy bit set and delay the stop as well. Since you are using the FIFO for transmission, there should'nt be any dead time between transmits. As soon as the TXRDY bit goes high the internal state machine should load up the next byte into I2CDXR and transmit.
Simon,
I'm new to I2C, but I will try to help you out. :-) If you're not going to do a read-back after sending the data, you might try using the STP bit only after you're done with all the writes. You should be able to do this by changing a line in I2CA_WriteData:
// Send start as master transmitter
I2caRegs.I2CMDR.all = 0x6E20; //Change 0x6E20 to 0x6620 to disable automatic STOP when buffer is empty
When you're done sending all the data, you could do:
while (I2caRegs.I2CSTR.bit.BB == 1) {;}
I2caRegs.I2CMDR.bit.STP = 1;
while (I2caRegs.I2CMDR.bit.STP == 1) {;}
or something like that. Another thing you could do is check whether any error flags are being set in I2CSTR after the third write. Also, please double-check that you're getting the right prescaler in I2CA_Init().
Let me know if none of this helps and I'll work on it some more.
Hi all,
Thanks for responding.
I tried changing the value of the register to disable the automatic STOP - no change.
The prescaler that is set in I2CA_Init is the one for the 150MhZ frequency, namely 14.
You have suggested waiting on the BB, setting the STP and waiting for it to become unset after all the transmissions. With this scenario I received one message on my Aardvark device.
Our 'actual' piece of hardware runs at a very slow 20KHz, (due to h/w constraints), this is well within the range for I2C, but is it so low that it's not really been tested here?
Currently the vanilla units I'm testing this problem on can handle up to 800KHz.
I can't believe I can't simply write or read from these devices as frequent as I wish and only be constrained by the maximum operating bus throughput. :-(
Simon.