avr-chat
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-chat] AVR EEPROM cell: Does 0xff mean it it is erased?


From: Heike C. Zimmerer
Subject: [avr-chat] AVR EEPROM cell: Does 0xff mean it it is erased?
Date: Sun, 18 Oct 2009 11:17:26 +0200
User-agent: Thunderbird 2.0.0.23 (X11/20090817)

Hello,

can I safely assume that if an EEPROM cell contains 0xff, it doesn't
need to be erased before writing to it?

Most newer AVRs offer the possibility to split erase and write to EEPROM
into two separate tasks, each of them taking about half the execution
time.  Now let's assume I write some state data (12 bytes each) into
consecutive locations (ring buffer) every, say, 5 minutes.  Under normal
conditions, there's no need to separate the tasks, but I do it anyway
(for reasons explained later) and I can make sure the next location
has been previously erased when it is written to.

However, when an external power down interrupt occurs, I need to write
the same data as fast as possible.  Under normal circumstances, I know
where to write to and I know the area has been erased before so I can
use the faster write-only cycle and skip erase.

Things change when the power down INT occurs while the main program is
writing a record (i.e., the INT falls exactly into a small time slot of
22 ms every 5 minutes).  Then I don't know which part of the record
already has been written out (I could keep track of but currently I hope
I don't need to) and I need to write to the same area again.

I can safely assume at most 4 of the 12 bytes will differ from what the
main program was just trying to write, so - my idea which needs to be
verified - if I compare the contents of the cells against the new data,
do nothing if they match, do a full erase/write if they differ, and do a
write-only if the cell contains 0xff, I could go on without increasing
the time needed for powering down.  Of cause, this only works if 0xff in
a cell means it doesn't need to be erased.

Then there was this problem with earlier AVRs where an erased cell would
read 0x0 at low voltages, but - if I remember correctly - read 0xff when
previously having been written to with 0xff.  I don't know for sure if I
remember this correctly.  This may indicate that there is a difference
between being erased and being written to with 0xff.

Does anybody know more about that?  As an illustration, I include the
current untested draft of the EEPROM write function:

----------------------
/*C
   void eeprom_write_byte_fast(uint8_t *eeaddr, uint8_t data);

   /# Write a byte to a (most possibly) erased ee-cell (faster than normal
   write if the area has been erased previously).
   
   If the cell is not yet erased, add erase cycle.  If the cell already
   contains the target data, return immediately. #/
*/
              .global eeprom_write_byte_fast
eeprom_write_byte_fast:
              sbic  _SFR_IO_ADDR(EECR),EEPE
              rjmp  eeprom_writeNE_byte ; eeprom not yet ready
              out   _SFR_IO_ADDR(EEARH),r25
              out   _SFR_IO_ADDR(EEARL),r24 ; set addr
              sbi   _SFR_IO_ADDR(EECR),EERE ; get current contents of the cell
              in    r23,_SFR_IO_ADDR(EEDR)
              cpi   r22,r23         ; already same?
              breq  ewRet           ; yes.  Nothing to do.
              out   _SFR_IO_ADDR(EEDR),r22 ; set data
              ldi   r20,1<<EEPM1|1<<EEMPE ; assume write only
              cpi   r23,0xff        ; is cell really erased already?
              breq  ewWriteNow      ; yes
              ldi   r21,1<<EEMPE    ; No.  Do a full erase/write cycle
ewWriteNow:   in    r21,_SFR_IO_ADDR(SREG) ; save INT flag
              cli
              out   _SFR_IO_ADDR(EECR),r20
              sbi   _SFR_IO_ADDR(EECR),EEPE ; start writing
              out   _SFR_IO_ADDR(SREG),r21 ; restore INT flag
ewRet:        ret
----------------------


Thanks,

Heike





reply via email to

[Prev in Thread] Current Thread [Next in Thread]