[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] Macro to read /write long to eeprom
From: |
David Kelly |
Subject: |
Re: [avr-gcc-list] Macro to read /write long to eeprom |
Date: |
Wed, 10 Aug 2005 20:20:15 -0500 |
On Wed, Aug 10, 2005 at 11:00:20AM +0200, Branislav Katreniak wrote:
Another trick is not to clear the byte in eeprom before the write when
it is sufficient to only clear bits on order to store the value into
eeprom (you save half of the write). There is some datasheet on atmel
site about this.
Which datasheet, please? Which AVR?
What you describe is what we used to do on 68HC11E1. When it came time
to write to EE on Atmega64 I found the control structure was different
in that one does not have separate clear and set steps when writing.
This is the eeprom write routine I use. Later compared to the hand
assembly in avr-libc and found the code size and steps performed were
almost identical. Given that, I'd rather use my own in C under my own
source control.
Notice how it reads first and skips the write if data is identical.
This is the only routine I use for writing EEPROM. If I only write one
byte then this just requires a little extra call setup. Don't see any
point in having another routine with only 2 args rather than 3.
//
// write to EEPROM
// addr is the address within the EEPROM
// cp is where to read data in RAM
// n is the number of 8 bit octets to copy
//
// ee_writes( sram source, ee dest, count );
//
void
ee_writes(const void *cp, void *addr, uint16_t n)
{
uint8_t sreg; // store SREG
for( ; n ; n-- ) {
wdt_reset();
while( EECR & (1<<EEWE) ) // wait until ready
;
EEAR = (uint16_t)addr++;
EECR |= (1<<EERE); // start a read
// Don't write unless the contents have changed:
if( EEDR != *((uint8_t*)(cp)) ) {
EEDR = *((uint8_t*)(cp)); // looks frightening
sreg = SREG; // save SREG to preserve global IRQ
cli(); // an IRQ would ruin this timing
EECR |= (1<<EEMWE); // only stays set for 4 clocks
EECR |= (1<<EEWE); // hit EEWE before EEMWE clears
SREG = sreg; // restore prev global IRQ state
}
cp++;
}
}
--
David Kelly N4HHE, address@hidden
========================================================================
Whom computers would destroy, they must first drive mad.