[Top][All Lists]
[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