eeprom write errors?

Started by Phil October 11, 2004

--- In , Chad Russel <chadrussel@y...> wrote:
> Sorry, that was a bad typo:
>
> After setting WR bit, enable interrupts (if used), then clear the WREN
> bit. If it works, then just do it. :-p It is a PhD's job to analyze
> everything to death.
>
> Chad
>

I've been developing sw for 25 years and taught 5 years at the college
level. Too often I've seen people fix a symptom and not the
underlying problem. Eventually, it comes back to haunt them. Fix it
now or fix it later. When I can't fully explain why my fix solves the
problem, it keeps gnawing at me. Maybe I'm just picky but I like to
know that my code is correct and doesn't have a landmine to step on.





--- In , "Phil" <phil1960us@y...> wrote:
> When I can't fully explain why my fix solves the
> problem, it keeps gnawing at me. Maybe I'm just picky but I like to
> know that my code is correct and doesn't have a landmine to step on.

Did you check the errata for this part? Some revs of the silicon have
an issue with writing to EEPROM and there is a work around provided.
Might be worth reading...




> I've been developing sw for 25 years and taught 5 years at the college
> level. Too often I've seen people fix a symptom and not the
> underlying problem. Eventually, it comes back to haunt them. Fix it
> now or fix it later. When I can't fully explain why my fix solves the
> problem, it keeps gnawing at me. Maybe I'm just picky but I like to
> know that my code is correct and doesn't have a landmine to step on.

Post your code here and we will take a look at it...

Regards,
Igor



uh, dang, that's it. I should have checked the errata (I'll write
that 100 times...).

Unfortunately, their work around is a mess - sleep while writing. I
dont think my app can tolerate the timer being suspended even for a
few cycles as it accumulates. I'll just stick with verify/retry. I
have yet to see a verify failure with my "wren" fix. Interestingly,
they clear WREN in their example code right after the sleep instruction.

This also affects 16F627As and 16F628As made before week 20 of 2004.

Thanks, Scott!

--- In , "Scott Lee" <midl_man@y...> wrote:
>
> --- In , "Phil" <phil1960us@y...> wrote:
> > When I can't fully explain why my fix solves the
> > problem, it keeps gnawing at me. Maybe I'm just picky but I like to
> > know that my code is correct and doesn't have a landmine to step on.
>
> Did you check the errata for this part? Some revs of the silicon have
> an issue with writing to EEPROM and there is a work around provided.
> Might be worth reading...




Phil,

Strange, I never had problems with my '628A's
EEPROM-write, altough I they are made before that
date.
I think it's time you showed us your code, and I'll
show you the code that I use (which is very standard I
think).

BSF STATUS, RP0 ; Bank1
MOVFW CONFIG_ADDR ;
MOVWF EEADR ; Address to write
MOVFW CONFIG_DATA ;
MOVWF EEDATA ; Data to write
BSF EECON1, WREN ; Enable Write
BCF INTCON, GIE ; Disable Interrupts
MOVLW 0x55 ; Write 0x55
MOVWF EECON2 ;
MOVLW 0xAA ; Write 0xAA
MOVWF EECON2 ;
BSF EECON1, WR ; set WR bit
BTFSC EECON1, WR ; still set?
GOTO $-1 ; wait until cleared
BCF EECON1, WREN ; Disable more Writes
BSF INTCON, GIE ; Enable Interrupts
BCF STATUS, RP0 ; Bank0

Hope we'll tackle this problem soon,

Kees Stenekes
--- Phil <> wrote:

>
> uh, dang, that's it. I should have checked the
> errata (I'll write
> that 100 times...).
>
> Unfortunately, their work around is a mess - sleep
> while writing. I
> dont think my app can tolerate the timer being
> suspended even for a
> few cycles as it accumulates. I'll just stick with
> verify/retry. I
> have yet to see a verify failure with my "wren" fix.
> Interestingly,
> they clear WREN in their example code right after
> the sleep instruction.
>
> This also affects 16F627As and 16F628As made before
> week 20 of 2004.
>
> Thanks, Scott!
>
> --- In , "Scott Lee"
> <midl_man@y...> wrote:
> >
> > --- In , "Phil"
> <phil1960us@y...> wrote:
> > > When I can't fully explain why my fix solves
> the
> > > problem, it keeps gnawing at me. Maybe I'm just
> picky but I like to
> > > know that my code is correct and doesn't have a
> landmine to step on.
> >
> > Did you check the errata for this part? Some revs
> of the silicon have
> > an issue with writing to EEPROM and there is a
> work around provided.
> > Might be worth reading... >
>

_______________________________




I am with you, however the underlying problem seems to be with
Microchip. We can contact Microchip for input, accept that what they
suggest works and leave it at that, or try to read the mind of the
silicon.

:)
Chad
--- Phil <> wrote:

>
> --- In , Chad Russel <chadrussel@y...> wrote:
> > Sorry, that was a bad typo:
> >
> > After setting WR bit, enable interrupts (if used), then clear the
> WREN
> > bit. If it works, then just do it. :-p It is a PhD's job to
> analyze
> > everything to death.
> >
> > Chad
> >
>
> I've been developing sw for 25 years and taught 5 years at the
> college
> level. Too often I've seen people fix a symptom and not the
> underlying problem. Eventually, it comes back to haunt them. Fix it
> now or fix it later. When I can't fully explain why my fix solves
> the
> problem, it keeps gnawing at me. Maybe I'm just picky but I like to
> know that my code is correct and doesn't have a landmine to step on. >
>


=====
My software has no bugs, only undocumented features.
_______________________________




ok, I'll post it. The main difference I see between yours and mine is
that I use EEIF to determine completion and you use WR bit. Datasheet
implies both should work (yours is a couple bytes shorter and its more
portable, I may switch). Are your config and data registers supposed
to be in bank 1? I prefer using BANKSEL since I use this code on
multiple PICs and Microchip keeps moving the eeprom SFRs around.
banksel makes it easy to move around.

address is in eeaddress and data is in W. note the verify code at the
end. I suppose yahoo will ruin the formatting... BANKSEL vtmp
movwf vtmp ; save data for verification, added 10/9/04
BANKSEL EEDATA
movwf EEDATA ; value to be written in W
BANKSEL eeaddress
movfw eeaddress ; get write address
BANKSEL EEADR
movwf EEADR ; write address
bsf EECON1, WREN ; enable write
bcf INTCON, GIE ; disable ints
movlw 0x55 ; voodoo sequence - see datasheet for details
movwf EECON2
movlw 0xAA
movwf EECON2
bsf EECON1, WR ; start write sequence
bcf EECON1, WREN ; clear enable bit added 10/9/04

BANKSEL PIR1 ; change for 877
eew0
btfss PIR1,EEIF ; is the EE flag set?
goto eew0 ; N: try again
bcf PIR1,EEIF ; Y: clear it
bsf INTCON, GIE ; re-enable ints

;
; verify write, added 10/07/04
;
call eeread ; read the location we just wrote to
subwf vtmp,w ; get the original value
skpnz ; Is the value written same as read?
return ; Y: return
movfw vtmp ; N: set up to retry
goto eewrite ; retry. --- In , Kees Stenekes <knalkeez@y...> wrote:
> Phil,
>
> Strange, I never had problems with my '628A's
> EEPROM-write, altough I they are made before that
> date.
> I think it's time you showed us your code, and I'll
> show you the code that I use (which is very standard I
> think).
>
> BSF STATUS, RP0 ; Bank1
> MOVFW CONFIG_ADDR ;
> MOVWF EEADR ; Address to write
> MOVFW CONFIG_DATA ;
> MOVWF EEDATA ; Data to write
> BSF EECON1, WREN ; Enable Write
> BCF INTCON, GIE ; Disable Interrupts
> MOVLW 0x55 ; Write 0x55
> MOVWF EECON2 ;
> MOVLW 0xAA ; Write 0xAA
> MOVWF EECON2 ;
> BSF EECON1, WR ; set WR bit
> BTFSC EECON1, WR ; still set?
> GOTO $-1 ; wait until cleared
> BCF EECON1, WREN ; Disable more Writes
> BSF INTCON, GIE ; Enable Interrupts
> BCF STATUS, RP0 ; Bank0
>
> Hope we'll tackle this problem soon,
>
> Kees Stenekes >
> --- Phil <phil1960us@y...> wrote:
>
> >
> > uh, dang, that's it. I should have checked the
> > errata (I'll write
> > that 100 times...).
> >
> > Unfortunately, their work around is a mess - sleep
> > while writing. I
> > dont think my app can tolerate the timer being
> > suspended even for a
> > few cycles as it accumulates. I'll just stick with
> > verify/retry. I
> > have yet to see a verify failure with my "wren" fix.
> > Interestingly,
> > they clear WREN in their example code right after
> > the sleep instruction.
> >
> > This also affects 16F627As and 16F628As made before
> > week 20 of 2004.
> >
> > Thanks, Scott!
> >
> > --- In , "Scott Lee"
> > <midl_man@y...> wrote:
> > >
> > > --- In , "Phil"
> > <phil1960us@y...> wrote:
> > > > When I can't fully explain why my fix solves
> > the
> > > > problem, it keeps gnawing at me. Maybe I'm just
> > picky but I like to
> > > > know that my code is correct and doesn't have a
> > landmine to step on.
> > >
> > > Did you check the errata for this part? Some revs
> > of the silicon have
> > > an issue with writing to EEPROM and there is a
> > work around provided.
> > > Might be worth reading...
> >
> >
> >
> >
>
> _______________________________
>



My config- and data registers are located from address
0x0070 (accessible in all banks), typical for a
16f628a. BANKSEL is better for running on different
pics indeed.
The other difference I see is that you clear the
WREN-bit BEFORE you check for the end-of-write. I
don't know if that has anything to do with it, but I
will try your code tomorrow and see what happens.

Kees.

--- Phil <> wrote:

>
> ok, I'll post it. The main difference I see between
> yours and mine is
> that I use EEIF to determine completion and you use
> WR bit. Datasheet
> implies both should work (yours is a couple bytes
> shorter and its more
> portable, I may switch). Are your config and data
> registers supposed
> to be in bank 1? I prefer using BANKSEL since I use
> this code on
> multiple PICs and Microchip keeps moving the eeprom
> SFRs around.
> banksel makes it easy to move around.
>
> address is in eeaddress and data is in W. note the
> verify code at the
> end. I suppose yahoo will ruin the formatting... > BANKSEL vtmp
> movwf vtmp ; save data for verification, added
> 10/9/04
> BANKSEL EEDATA
> movwf EEDATA ; value to be written in W
> BANKSEL eeaddress
> movfw eeaddress ; get write address
> BANKSEL EEADR
> movwf EEADR ; write address
> bsf EECON1, WREN ; enable write
> bcf INTCON, GIE ; disable ints
> movlw 0x55 ; voodoo sequence - see datasheet for
> details
> movwf EECON2
> movlw 0xAA
> movwf EECON2
> bsf EECON1, WR ; start write sequence
> bcf EECON1, WREN ; clear enable bit added 10/9/04
>
> BANKSEL PIR1 ; change for 877
> eew0
> btfss PIR1,EEIF ; is the EE flag set?
> goto eew0 ; N: try again
> bcf PIR1,EEIF ; Y: clear it
> bsf INTCON, GIE ; re-enable ints
>
> ;
> ; verify write, added 10/07/04
> ;
> call eeread ; read the location we just wrote to
> subwf vtmp,w ; get the original value
> skpnz ; Is the value written same as read?
> return ; Y: return
> movfw vtmp ; N: set up to retry
> goto eewrite ; retry. > --- In , Kees Stenekes
> <knalkeez@y...> wrote:
> > Phil,
> >
> > Strange, I never had problems with my '628A's
> > EEPROM-write, altough I they are made before that
> > date.
> > I think it's time you showed us your code, and
> I'll
> > show you the code that I use (which is very
> standard I
> > think).
> >
> > BSF STATUS, RP0 ; Bank1
> > MOVFW CONFIG_ADDR ;
> > MOVWF EEADR ; Address to write
> > MOVFW CONFIG_DATA ;
> > MOVWF EEDATA ; Data to write
> > BSF EECON1, WREN ; Enable Write
> > BCF INTCON, GIE ; Disable Interrupts
> > MOVLW 0x55 ; Write 0x55
> > MOVWF EECON2 ;
> > MOVLW 0xAA ; Write 0xAA
> > MOVWF EECON2 ;
> > BSF EECON1, WR ; set WR bit
> > BTFSC EECON1, WR ; still set?
> > GOTO $-1 ; wait until cleared
> > BCF EECON1, WREN ; Disable more Writes
> > BSF INTCON, GIE ; Enable Interrupts
> > BCF STATUS, RP0 ; Bank0
> >
> > Hope we'll tackle this problem soon,
> >
> > Kees Stenekes
> >
> >
> >
> > --- Phil <phil1960us@y...> wrote:
> >
> > >
> > > uh, dang, that's it. I should have checked the
> > > errata (I'll write
> > > that 100 times...).
> > >
> > > Unfortunately, their work around is a mess -
> sleep
> > > while writing. I
> > > dont think my app can tolerate the timer being
> > > suspended even for a
> > > few cycles as it accumulates. I'll just stick
> with
> > > verify/retry. I
> > > have yet to see a verify failure with my "wren"
> fix.
> > > Interestingly,
> > > they clear WREN in their example code right
> after
> > > the sleep instruction.
> > >
> > > This also affects 16F627As and 16F628As made
> before
> > > week 20 of 2004.
> > >
> > > Thanks, Scott!
> > >
> > > --- In , "Scott Lee"
> > > <midl_man@y...> wrote:
> > > >
> > > > --- In , "Phil"
> > > <phil1960us@y...> wrote:
> > > > > When I can't fully explain why my fix
> solves
> > > the
> > > > > problem, it keeps gnawing at me. Maybe I'm
> just
> > > picky but I like to
> > > > > know that my code is correct and doesn't
> have a
> > > landmine to step on.
> > > >
> > > > Did you check the errata for this part? Some
> revs
> > > of the silicon have
> > > > an issue with writing to EEPROM and there is a
> > > work around provided.
> > > > Might be worth reading...
> > >
> > >
> > >
> > >
> >
> >
> >
> >
> > _______________________________
> >

_______________________________





--- In , Kees Stenekes <knalkeez@y...> wrote:
> My config- and data registers are located from address
> 0x0070 (accessible in all banks), typical for a
> 16f628a. BANKSEL is better for running on different
> pics indeed.
> The other difference I see is that you clear the
> WREN-bit BEFORE you check for the end-of-write. I
> don't know if that has anything to do with it, but I
> will try your code tomorrow and see what happens.

I wasn't clearing the WREN bit at all before, adding that instruction
made my eewrite routine work reliably. All the WREN bit is supposed
to do, according to the datasheet, is inhibit the setting of WR bit.
Clearly, it has more effect than just that.

Just to be clear, the code I posted works reliably for me. The WREN
and retry code was added during this thread. If you are going to try
the code, remove the bcf EECON1, WREN line. With out that line, I
was getting about 10% write failures.

By the way, the Microchip simulator doesn't update the EEPROM location
until my code tests the EEIF bit. I dont know if that has any bearing
on how the chip actually works, though.



Hello Phil,

*DO NOT* use "bcf INTCON, GIE" do disable interrupts!

This is how you disable interrupts on PIC MCUs:

loop bcf INTCON, GIE
btfsc INTCON, GIE
goto loop

For details, download and read AN576 "Techniques to Disable Global
Interrupts".

You should clear WR bit *AFTER* writing to eeprom is completed (after
checking PIR1,EEIF), not before!

Everything else is OK although I like placing few NOPs after "bsf EECON1,
WR" :)

Regards,
Igor