Safe to change EEAR immediately following reading EEDR?

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The subject almost says it all.. Is it OK to have the following instructions in succession without any time passing between commands, regardless of clock speed? Is the value immediately available after a read strobe? Does changing the eeprom address register immediately following reading from the eeprom data register endanger the value just being read, or is register1 completely and correctly loaded? And is EEAR really set to register2 value .. for the next instruction executed after this is over.. ?

sbi EECR, EERE ; strobe the eeprom read
in register1, EEDR ; get the value
out EEAR, register2 ; move the eeprom address pointer

Wondering if tight code here is the wrong place to be tight.. thanks

Regards,
Scott

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You did not specify which AVR processor.

You need to read the data sheet or sheets for the AVR or AVRs you are interested in. Read the EEPROM Data Memory section, especially the assembly language examples and your questions should be answered. BTW, don't forget to look at the data sheet errata section also (sometimes the errata is in a different document).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Check to make sure the EEprom is not busy writing before starting the read or a write operation. As you do not want to wait around several millisecs after starting a write.

Keep it simple it will not bite as hard

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's a '1200. I'm only talking about reads. My question is related to clarifying what I see in the spec.. The specs says things about EEPROM read that make me suspicious.. it says,

"The EEPROM Read Enable Signal (EERE) is the read strobe to the EEPROM. When the correct address is set up in the EEAR register, the EERE bit must be set. When the EERE bit is cleared (zero) by hardware, requested data is found in the EEDR register. The EEPROM read access takes one instruction and there is no need to poll the EERE bit. When EERE has been set, the CPU is halted for four cycles before the next instruction
is executed."

It says you could poll the EERE for a zero before fetching data from EEDR. ..but you don't need to .. because it only takes one cycle to complete. Then why mention it? It also says that strobing the read forces a 4 cycle wait before the next command (the 'in" command in my code example) executes. This implies some time must pass before a read is valid and done. But at different clock frequencies, this would be different amounts of wall-clock time. (I'm running on internal RC = approx. 1MHz).

So, regardless of clock chosen (within spec limits)... do I have to worry about inserting NOP's (or the like) in my code snippet? Or can we comfortably blast through an array of reads from EEPROM like this?

thanks

Regards,
Scott

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cautionary note which may or may not be relevant: Some months ago
someone here was having trouble with back-to-back writes to his UART.
The spin-and-store sequences were inline, such that the code contained
the sequence "out UDR,mumble; sbis USR,UDRE". When I simulated
this sequence I was surprized to see that the "sbis" always succeeded
since the UDRE hadn't yet cleared from the "out" by the time the USR
was fetched in the next instruction. (The fact that the OP was seeing
the same high-level symptom indicated that this was not just a simulator
thing.) Inserting a NOP took care of the problem.

Someone much smarter than me was able to explain this apparent
propagation delay based on a timing diagram in the Data Sheet, but
I never was able to read the runes correctly. There was certainly no
text which said explicitly that this could happen. (This is the kind of
thing that makes Software People superstitious (:-)).)

So there seems to exist (at least) one obliquely-documented sub-cycle propagation
race in (at least) one AVR. Someone who's really good at this stuff can probably figure it out .
Me? I'd just insert the NOP and move on.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote from '1200 datasheet. This is valid for all devices as far as I know.

"The EEPROM read access takes one instruction and there is no need to poll the EERE
bit. When EERE has been set, the CPU is halted for four cycles before the next instruction
is executed."

/claus

/claus

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I see the EEPROM information in the AT90S1200 data sheet is kind of sparse. Code examples from other devices use this sequence in their examples:

sbi EECR, EERE ; strobe the eeprom read
in register1, EEDR ; get the value

However, they have code that always checks the EEWE bit in the EECR register before proceeding with an EEPROM read. Before proceeding also includes setting the EEAR register. This is what sutton was telling you.

Here is a modified representation of how EEPROM access is shown in other data sheet examples:

EEPROM_read:
sbic EECR, EEWE
rjmp EEPROM_read
;
out EEAR, register2
sbi EECR, EERE
in register1, EEDR
ret

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know the code for waiting for the EEWE to clear is best practice before accessing the eeprom for the first read. I got that code in. But once that wait is over, must I insert a wait for EEWE prior to every successive eeprom byte read from an array? Would EEWE ever go "busy state" in the middle of successive reads? I'm *really* tight on space and a NOP pains me (in principle alone!) but also especially if I don't need one here.

I wonder what the various C compilers generate in this space, if I weren't doing this one in asm. Hmm..

Regards,
Scott

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is no need for a nop instruction. However, I can not tell you if EEWE will do anything or not. You will have to ask ATMEL on this one.

If you want you program to work as reliably as possible, with any batch of production AVR chips, anytime, then you are best off by following example code from ATMEL. If you venture out on your own and it doesn't work, then at least you know not to use it. If you venture out on your own and it appears to work, well you will have to answer the reliability question all by yourself (short term reliability is easy, long term is a b***h to figure out).

Assuming you are already checking EEWE before setting at least the first EEAR address, maybe you can adjust your algorithm to avoid using the unchecked immediate write to EEAR and use the existing checked code instead.

Speaking of reliability, to help protect the EEPROM from corruption the AT90S1200 requires an external hardware Brown-out Detector (BOD). If you are relying on the EEPROM for good data, a BOD is highly recommended.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Take it easy here. The EEWE bit doesn't get set randomly. Only you as a programmer can set this bit. If you'r reading several bytes (a buffer fx) and you can guarantee that a EEPROM write doesn't occur in the middel then there's no reason to check the EEWE bit more than once.

/claus

/claus

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do not see why testing the EEWE should increase code size as it should be at the start of the read operation routine.

ie
check EEWE loop
load up address
move data byte to a working register
change address to 0 (to protect from false writes this location not used)
leave.

I would not get to interested in what the C compilers generate,
they can be wrong! As an example the IAR (in version 1.5) did not disable interrupts when starting the eeprom write.

Keep it simple it will not bite as hard

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sutton wrote:
I would not get to interested in what the C compilers generate,
they can be wrong! As an example the IAR (in version 1.5) did not disable interrupts when starting the eeprom write.

That might not be wrong, rather trying not to be redundant.

I have a related question. Is it o.k. to clear the EEAR address register immediately after starting a write cycle so as to protect against spurious writes as soon as the cycle finishes? This seems to work on an ATtiny26 but I haven't risked it on a customer. (I already take at least a half dozen measures to avoid, detect and correct eeprom corruption. :roll:)

- John

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

*Claus* wrote:
Take it easy here. The EEWE bit doesn't get set randomly...

Maybe I'm overly cautious. Obviously EEWE is tied to the EEPROM write function. However, its consistently used as a busy flag for all reads in the data sheets and I'm in the dark as to the internal design of the EEPROM circuits. I can't guarantee the EEWE bit will only ever become active when writing to it. Low Vcc or something else might set it off, I just don't know. That's why I said ATMEL has the answer. I just do not feel comfortable telling someone that its OK to go ahead an write their program a certain way, contrary to the data sheets, based on my ignorance (not that I have any control on how their programs are written anyway). Its nothing to do with ATMEL EEPROMs, but I've been burned in the past by blind assumptions that the obvious must work the way I think it should, just because it appears to make sense and appeared to work without long term comprehensive testing.

If I really needed to save two cycles from the EEWE test, in this case I would at least ask ATMEL support if there was any problem not checking EEWE when only reading the chip.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I have a related question. Is it o.k. to clear the EEAR address register immediately after starting a write cycle so as to protect against spurious writes as soon as the cycle finishes? This seems to work on an ATtiny26 but I haven't risked it on a customer. (I already take at least a half dozen measures to avoid, detect and correct eeprom corruption. :roll:)

Oh, don't even get me started on EEPROM writes!! I also use "belt and suspenders" mode for writes. Among many things, I've added another "EEWE bit" flag of my own (using a gen.purpose register) and if it's not set the way I want it (helps detect random execution) I jump out of the eeprom write process. One gen.purpose register is dedicated for holding eeprom data, and I always keep it loaded with default values (bits) that I can tolerate being written if done by mistake. It boils down to this: if a random jump happens to land exactly on the EEPROM write strobe, then a bad value gets written. But in this case EEAR has been left pointing somewhere that I don't care and use, guess where.. eseg address zero.

I do change EEAR immediately after the EEWE bit tells me it has cleared itself, after making the write.

..set eeprom value..
..set eeprom address..
sbi EECR,EEWE
WAIT:
sbic EECR,EEWE
rjmp WAIT
clr Acc1
out EEAR,Acc1

Regards,
Scott

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interrupts should be disabled durring the write enable and starting. This particular bad bit of coding was an inline macro, and the compiler had no way of knowing if at the point of insertion the interrupts were in use or not.

Also as an inline macro after three calls it required more space than if a proper function call was used.

Keep it simple it will not bite as hard

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

scottm wrote:
Oh, don't even get me started on EEPROM writes!! I also use "belt and suspenders" mode for writes.

I am not the only one who does such things. I would be perfectly happy to just enable the BOD and forget about the whole issue, but that is simply not enough. The latest amusement is from a guy who had to "recode" a controller every two months because its EEPROM keeps losing most of its contents. I have been poking at it for a while and can't make it fail. My investigations and the circumstances pretty much rule out all the usual suspects. I am starting to wonder if low current spikes on the ATtiny26's inputs may be slowly erasing the EEPROM. The guy added some non-approved HID lights to his car which are probably injecting transients into the electrical system.

Quote:
I do change EEAR immediately after the EEWE bit tells me it has cleared itself, after making the write.

I clear EEAR at the next convenient opportunity which, for the writes that matter, is a couple milliseconds after the chip reports they have finished. If I were designing the chip, I would have it latch a copy of EEAR as a write starts so that you could write the EEPROM and clear EEAR to protect it against subsequent, spurious writes, all in one fell swoop.

- John

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jfiresto wrote:
I am not the only one who does such things. I would be perfectly happy to just enable the BOD and forget about the whole issue, but that is simply not enough.

There is more too it than just turning on the BOD. The BOD level selection is critical. For example, an AVR running at 16 Mhz that is rated to have 4.5 to 5 volt Vcc at high clock speeds, is going into a gray area when Vcc falls below 4.5 volts. It obvious that 4.4 volts is not a problem, but somewhere that 16 MHz clock speed will outrun the Vcc level if Vcc keeps dropping. If the chip can not keep up with its own clock speed and the BOD has not kicked in yet, then the AVR may do random things including overwriting the EEPROM. The point is the BOD level needs to be matched to the clock speed the AVR is running at. If the internal BOD does not have the correct trip range, then use an external BOD chip.

Automotive power sources are a really rough on MCU power. If the AVR is powered from the vehicle, throughout the engine starting process, then Vcc levels are probably going all over the map every time the key is turned.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps I phrased things in a way that can be too narrowly interpreted. I hope everyone understands you should choose a brown out voltage so that the BOD resets the processor before it starts to malfunction! The above controller uses 2.7V so that it doesn't reset during engine cranking, and a 2mhz clock frequency to yield a low quiescent current. It also detects external power failures and finishes writing the EEPROM before the 5V supply reaches the brown out voltage.

- John

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I would be perfectly happy to just enable the BOD and forget about the whole issue, but that is simply not enough.

In my experience, that is simply not true.

We have dozens of industrial AVR apps. All of them use EEPROM to some extent or another. The AVRs range from the '2313 and Tinys up to Mega64, with many stops in between.

I have yet to find a single instance of EEPROM [or flash] corruption, either on the bench or in the field. I've examined dozens of units coming back from the field for whatever reason, and not a single one has the "guard" value in the first byte disturbed.

Almost all are 5V Vcc designs. All have either internal brownout detector enabled or an external brownout detector installed. Most use CodeVision's native primitives, which don't do anything special with EEAR.

All that said, I've seen too many posts from knowledgable people as in this thread to figger that there has to be SOMETHING lurking in the dark woods.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.