avr-gcc-list
[Top][All Lists]
Advanced

[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.





reply via email to

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