Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

Re: [AVR-Chat] Saving in EEPROM without corruption?

2004-10-02 by Dave VanHorn

>
>        I have a 2313 working on a very noisy environment and subject
>to eventual crashes that corrupt the EEPROM. Any address.
>        And I'm not allowed to modify the hardware at this time.
>
>        Well, two 'nops' inserted in the EEPROM write routine seem to 
>have cured the problem. See below:
>
>                cli
>                out     EEARL, address
>                out     EEDR, data
>                sbi     EECR, EEMWE
>                nop                                     ; Inserted
>                nop                                     ; Inserted
>                sbi     EECR, EEWE
>                clr     address
>                out     EEARL, address
>                sei

Interesting.  I don't see why this would help though.
It doesn't widen the window of opportunity though.
In the overall scheme of things, it would just seem to delay the write a bit.

I don't see you waiting until the write is complete here, is there a possibility you're coming back in for another write before this write is complete?

Here's the routine I use in the larger chips, which includes a few checks that you aren't doing.


;********************************************************************
;Put a single byte in EEPROM, safely per manual, with optiona readback verify
;Call with pointer to EEPROM in X, data in TEMP.
;Increments X, Trashes TEMP2
;********************************************************************
;
Save_EE:

        ;APPARENT EMULATOR BUG IN THE ICE200 REQUIRES THAT
        ;YOU POLL FOR /EEWE AND /EERE BEFORE WRITING, AFTER A READ

        rcall   Timed_Smack             ;In case the loop takes a while
        in      TEMP2,EECR              ;Poll for ready
        andi    TEMP2,3                 ;Both bits must be zero
        brne    Save_EE                 ;Loop till zero

        out     EEARH,XH                ;Point at the current cell
        out     EEARL,XL                ;
        out     EEDR,TEMP               ;Data's ready to be saved
        adiw    XL,1                    ;Increment the address for next call

        ;WARNING: This section cannot be single-stepped in the
        ;emulator due to timing constraints.
        cli                             ;No ints now
        sbi     EECR,2 ;EEMWE           ;Set master write enable=1
        sbi     EECR,1 ;EEWE            ;Set write enable to 1, starts the write
        sei                             ;Ok, now you can bother me.
        ;End of critical section

        ;rjmp   Save_EE_Exit            ;If you don't want readback, then
                                        ;all you have to do is uncomment this line


        ;Now, we have to wait for the write to complete
Save_EE_Verify:
        ldi     TEMP2,Max_EE_Wait       ;Max mS to wait
        sts     EEPROM_Timer,TEMP2      ;
Save_EE_V_Loop:
        rcall   Timed_Smack             ;In case we wait through a WDT
        lds     TEMP2,EEPROM_Timer      ;
        and     TEMP2,TEMP2             ;Is it zero yet?
        breq    Save_EE_Bad2            ;If so, then signal failure >20ms to write

        in      TEMP2,EECR              ;Poll for EECR,EEWE=1 before continuing!
        andi    TEMP2,1 ;EEWE           ;
        brne    Save_EE_V_Loop          ;Potential to loop forever.


        ;Time to read the data
        ;Address is already set, so just read it back
        sbi     EECR,1 ;EERE            ;Set EE Read Enable
        in      TEMP2,EEDR              ;Get the data

        ;If unequal, then signal failure
        cp      TEMP,TEMP2              ;
        brne    Save_EE_Bad             ;

        ;otherwise
        clc                             ;Indicate success
        rjmp    Save_EE_Exit            ;

        ;Redundant code, but it lets me breakpoint and know which way it failed.

Save_EE_Bad:
        sec                             ;Data didn't match
        
Save_EE_Bad2:
        sec                             ;timeout on readback

Save_EE_Exit:
        ldi     TEMP2,$00               ;Point at non-existent location
        out     EEARL,TEMP2             ;when not in active use.
        out     EEARH,TEMP2             ;
        ret                             ;

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.