EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Corruption on reading from EEPROM

Started by merapcb June 15, 2010
merapcb wrote:
>
> --- In m..., Joerg wrote:
>
>> Have you tried looking at data and clock with an oscilloscope instead of
>> the logic analyzer?
>>
>> --
>
> Sorry, no I have not (I don't have that type of scope). Why would it be different? (or how?)
>

Not sure how long your traces are but a scope can show ringout. The
nasty kind of ringout could hit the parasitic substrate diodes which are
often slow, and mess up the timing. A logic analyzer doesn't show
ringing. Same goes for the snappiness of the transitions. For example,
any undesired capacitive load on I2C can round off the edges because
it's only resistors pulling up. Then the threshold on your logic
analyzer might be set to where it reads everything ok but the threshold
on your uC pin may be higher. On the MSP430 it would be around VCC/2.
Just examples.

You can watch it with pretty much any tpe of scope, even a really old
one with 10MHz bandwidth.

--
Regards, Joerg

http://www.analogconsultants.com/

"gmail" domain blocked because of excessive spam.
Use another domain or send PM.

Beginning Microcontrollers with the MSP430

On Wed, 16 Jun 2010 14:49:15 -0700, you wrote:

>Jon Kirwan wrote:
>
>[...]
>
>> I am curious what merapcb finds in the end. Assuming only
>> basic skills at hardware and software, it's hard to mess up.
>>
>> The only thing I can imagine is that merapcb is misreading
>> something in the docs and not implementing the software
>> correctly because of that or merapcb has more fundamental
>> software writing problems to deal with.
>>Or bad chips.

Yes. (Either I had already written that I hope he has more
chips to try or else thought it and failed to write it.)

>BTW, the hang-ups I saw in I2C were not caused by
>sub-optimal code but by devices inexplicably hogging the bus and never
>letting go.

Were these clock-stretching capable slaves? (Just curious.)

>The worst one required a power cycle to snap out of it.

Hmm. Whose parts should I avoid, then? :)

Jon
Jon Kirwan wrote:
> On Wed, 16 Jun 2010 14:49:15 -0700, you wrote:
>
>> Jon Kirwan wrote:
>>
>> [...]
>>
>>> I am curious what merapcb finds in the end. Assuming only
>>> basic skills at hardware and software, it's hard to mess up.
>>>
>>> The only thing I can imagine is that merapcb is misreading
>>> something in the docs and not implementing the software
>>> correctly because of that or merapcb has more fundamental
>>> software writing problems to deal with.
>>>
>> Or bad chips.
>
> Yes. (Either I had already written that I hope he has more
> chips to try or else thought it and failed to write it.)
>
>> BTW, the hang-ups I saw in I2C were not caused by
>> sub-optimal code but by devices inexplicably hogging the bus and never
>> letting go.
>
> Were these clock-stretching capable slaves? (Just curious.)
>
>> The worst one required a power cycle to snap out of it.
>
> Hmm. Whose parts should I avoid, then? :)
>

I don't remember, just kept using SPI for my own projects. It happened
on existing designs. Clock stretching wasn't the issue, the slave just
didn't come back (quit responding) or hogged the bus for good. The only
thing that got them out of the rut was a power cycle.

--
Regards, Joerg

http://www.analogconsultants.com/

merapcb wrote:
>
> Am posting the code.... :
>

Hi,
I don't see your higher level stuff here, and as you seem to be talking
to the chip ok, maybe that is where your problem is.

From the spec:
"RANDOM READ: A random read requires a dummy byte write sequence to
load in the
data word address..."

Meaning you have to do a write to set the address counter and without a
stop. Then another start condition again with the device address but as
read to read from a specific rom address.

Is all that happening? I have not tried the write with a stop as I'm in
control with bitbang, but that may be legal. I don't see why not. But I
don't remember reading it being ok in the spec. That would be a try it
out thing once you have known good legal protocol working.

Without random access you will certainly not read what you wrote as the
address counter keeps moving on.

Best, Dan.

> -------------------------------
>
> #include "Common_Def.h"
> #include "Controller.h"
> #define ALLOCATE
> #include "I2C_EEPROM.h"
>
> void vI2CInit(void)
> {
> P3SEL = (SDA + SCL); // select module function for the used I2C pins
> P3DIR&= ~(SDA + SCL);
>
> U0CTL |= I2C+SYNC; //Select I2C mode with SWRST=1
> U0CTL&= ~I2CEN; //disable the I2C module
> //Configure the I2C module with I2CEN=0 :
> // U0CTL default settings:
> // 7-bit addressing, no DMA, no feedback
> I2CTCTL = I2CTRX+I2CSSEL_2; // byte mode, repeat mode, clock source = SMCLK,
> // transmit mode
> I2CSA = 0x50; // Slave Address
> I2COA = 0x22; // own address.
> I2CPSC = 0x00; // I2C clock = clock source/1
> I2CSCLH = 0x03; // SCL high period = 5*I2C clock
> I2CSCLL = 0x03; // SCL low period = 5*I2C clock
> U0CTL |= I2CEN; // I2CEN via software
> }
> void vI2CEEPROMWrite(U8 Len)
> {
> while(I2CDCTL&I2CBUSY); // wait until I2C module has finished all operations
>
> // /*Device address and Write operation*/
> // I2CSA = 0x68;
>
> U0CTL |= MST; // define Master Mode
> I2CIFG&= ~TXRDYIFG;
> I2CIE = TXRDYIE; // enable Transmit ready interrupt
>
> u8TxCounter = 0; //Reset the transmit counter
>
> I2CNDAT = Len; //Length of the data
>
> I2CTCTL |= I2CTRX; // I2CTRX=0 => Transmit Mode (R/W bit = 1)
>
> /*Set as Tx mode, Enable Start and Stop condition*/
> I2CTCTL |= I2CTRX + I2CSTT + I2CSTP;
> }
>
> void vI2CEEPROMRead(U8 Len)
> {
> while(I2CDCTL&I2CBUSY); // wait until I2C module has finished all operations
>
> U0CTL |= MST; // define Master Mode
>
> I2CIFG&= ~ARDYIFG; // clear Access ready interrupt flag
> I2CIFG&= ~RXRDYIFG;
>
> I2CIE = RXRDYIE; // enable Receive ready interrupt
>
> I2CTCTL&= ~I2CTRX; // I2CTRX=0 => Receive Mode (R/W bit = 1)
>
> u8TxCounter = 0;
> I2CNDAT = Len; //Length of the data
>
> I2CTCTL |= I2CSTT+I2CSTP; //Enable START and STOP condition
>
> while(I2CDCTL&I2CBUSY); // wait until I2C module has finished all operations
> }
> void vLocateEEPROMReadAddr(U8 Len)
> {
> while(I2CDCTL&I2CBUSY); // wait until I2C module has finished all operations
>
> U0CTL |= MST; // define Master Mode
>
> u8TxCounter = 0;
>
> I2CNDAT = Len; //1 byte should be transmitted
> I2CIFG&= ~TXRDYIFG; //Clear Transmit ready interrupt flag
> I2CIE = TXRDYIE; //enable Transmit ready interrupt
>
> I2CTCTL |= I2CTRX; // I2CTRX=0 => Transmit Mode (R/W bit = 1)
>
> I2CTCTL |= I2CTRX + I2CSTT + I2CSTP; //Set as Transmitter, enable START and
> // STOP condition
> }
> /*-----*/
> #pragma vector=USART0TX_VECTOR
> __interrupt void ISR_I2C(void)
> {
> switch (I2CIV)
> {
> case I2CIV_RXRDY: /* Receive ready (RXRDYIFG) */
> {
> I2CReadBuffer[u8TxCounter+2]=I2CDRB; // store received data in buffer
> u8TxCounter++;
> break;
> }
> case I2CIV_TXRDY: /* Transmit ready (TXRDYIFG) */
> {
> I2CDRB = I2CBuffer[u8TxCounter++];
>
> if (u8TxCounter == I2CNDAT)
> {
> I2CIE&= ~TXRDYIE; // disable interrupts
> }
> break;
> }
> case I2CIV_ARDY: /* Access ready (ARDYIFG) */
> {
> I2CIFG&= ~ARDYIFG; // clear Access ready interrupt flag
> break;
> }
> case I2CIV_AL: /* Arbitration lost (ALIFG) */
> case I2CIV_NACK: /* No acknowledge (NACKIFG) */
> case I2CIV_OA: /* Own address (OAIFG) */
> case I2CIV_GC: /* General call (GCIFG) */
> case I2CIV_STT: /* Start condition (STTIFG) */
> break;
> }
> }
>
Joerg schrieb:
> Jon Kirwan wrote:
> > On Tue, 15 Jun 2010 16:23:57 -0700, Jg wrote:
> >
> >> Now don't hit me, but did you ground the WP pin?
> >
> > If it is left floating, it's tied internally towards ground I
> > think. But yes. I haven't used these parts and have never
> > tried to operate a part that was externally write protected.
> > I wonder if they even 'acknowledge' a write, if they are
> > protected. Do you know one way or the other? I'm curious,
> > now.
> > Don't know, I try to avoid I2C because of weird hang-up problems that I
> have seen too often in existing designs. I prefer SPI.

I totally agree with that. I had just that week a device with an I2C EEPROM
on which the master (MSP430 USCI) randomly stopped the clock in the middle
of a transmission. That did never happen on other devices of the same type
and after replacing the EEPROM the device worked well, again. Such errors
are very nasty to debug because you never know which device pulls the bus
low.

The problem is that I2C has many error conditions which your firmware all
has to properly handly especially if you use a dedicated hardware module
rather than bit-banging. Doing bit-banging, you sometimes have the
advantage of not having to check for arbitration errors or checking if the
bus is free, knowing you have only one master at the bus. But with SPI you
don't even have to think about that, it just works. With higher speed and
half of the development time.

Regards,
Markus
On Wed, 16 Jun 2010 15:50:47 -0000
"merapcb" wrote:

> --- In m..., Joerg wrote:
>
> > >
> >
> > Have you tried looking at data and clock with an oscilloscope instead
> > of the logic analyzer?
> >
> > --
>
> Sorry, no I have not (I don't have that type of scope). Why would it be
> different? (or how?)
>

Just one thing I could think about: do you wait for the device to be
ready writing before you start reading it out? I once encountered a
problem when I used code that worked perfectly fine on an FRAM to
read/write a real EEPROM which was much slower. The EEPROM required a lot
of wait stages after writing data to it.

HTH,

Hans

>
--


The 2024 Embedded Online Conference