EmbeddedRelated.com
Forums

Flash fails to write a bit or zeroes other bit

Started by chazeltopman May 21, 2004
I'm experiencing write failures of a bit in flash. If I
write the pattern 0xA55A to a location like 0x1DC10
and then write a vector to the following location,
0xDC14, I find that the first location has become
0xA558.
Now let me explain the write algorithm I'm using.
I need to be able to store 32 bit values into flash
one at a time. Since the IAP routines limit writes
to a minimum of 512 bytes I had to work around
this limit.
My current algorithm reads the location to be
written and if it is ones, then the sector does not
need to be erased and the 512 byte section
surrounding the word to be changed only needs
to be altered.
o 512 byte section is copied to RAM;
o 32-bit value is stored into the RAM image
o 512 byte image is written back to the Flash
using the IAP copy to Flash command.
Now the only funky thing I see here which might
be a problem is multiple writes to flash cells. In
some cases multiple writes to cells diminishes
the charge, but this is usually documented in the
user manual and I can't find any mention of it.
Anyone the wiser?
So now I use a dumb algorithm:
o copy 8K sector which contains location to be
altered, to RAM
o change location in RAM
o erase sector in flash with IAP command
o write back 8K sector with IAP command
Not only does this take a long time (400ms) but
I worry that I will run out of flash cycles.
To make matters more complicated, I'm also
working with the LPC2129 and I can't use the dumb
algorithm on it because there is only 16K of RAM
and two of the flash sectors are 64K! Also the
mapping of address to sector numbers no
longer is linear.

Sigh, no memory technology has everything yet.

Rob



An Engineer's Guide to the LPC2100 Series

--- In , "chazeltopman" <rob@n...> wrote:
> Now let me explain the write algorithm I'm using.
> I need to be able to store 32 bit values into flash
> one at a time. Since the IAP routines limit writes
> to a minimum of 512 bytes I had to work around
> this limit.

I've received an anonymous reply that addresses the
flash writing limitations:

: The flash can not be used '32 bit word' wise.
: You could try to write 16 bytes at once (4x 32 bit word),
: but the number of partial writes per 512 bytes (the normal
: size) is limited (I don't believe this number is specified).
:
: Note the '16 byte'data should be properly aligned on 16 byte
: multiples (but again the number of 'partial write'is limited
: .. let's say .. 16 times or so :-) ).
:
: You may repost this info in the group - as long as you
: don't refer to me.

Since counting the number of times I write to a location
presents a new bag of trouble, I'll use the dumb algorithm
of copy, modify, erase and write back. Sigh.

Rob



--- In , "chazeltopman" <rob@n...> wrote:
> Now let me explain the write algorithm I'm using.
> I need to be able to store 32 bit values into flash
> one at a time. Since the IAP routines limit writes
> to a minimum of 512 bytes I had to work around
> this limit.

I've received an anonymous reply that addresses the
flash writing limitations:

: The flash can not be used '32 bit word' wise.
: You could try to write 16 bytes at once (4x 32 bit word),
: but the number of partial writes per 512 bytes (the normal
: size) is limited (I don't believe this number is specified).
:
: Note the '16 byte'data should be properly aligned on 16 byte
: multiples (but again the number of 'partial write'is limited
: .. let's say .. 16 times or so :-) ).
:
: You may repost this info in the group - as long as you
: don't refer to me.

Since counting the number of times I write to a location
presents a new bag of trouble, I'll use the dumb algorithm
of copy, modify, erase and write back. Sigh.

Although, with a second thought, it might be worth a best-of
algorithm which does a:
o copy
o modify
o write
o compare
o if ok then done
o if different then do dumb algorithm

The question is, how much should be compared? If I compare
just the surrounding 512 byte section that I am writing to,
will the other sections in the 8K sector be affected? I
suspect not. But if the write fails, then the copied part
and the other sections from the flash must be merged to form
the new flash sector image.

Now what if I didn't have to write 512 bytes?
Does the reply suggest that I can use the IAP write command
with a value smaller than the stated 512 bytes? Hmmm... One
way to find out is the emperical method.... No. Only the
published values are accepted. So I tried to write the
whole section of 512 bytes multiple times and the most I
got was three good writes after an erase but mostly just
two. So overall, I could cut the time in half by only
erasing every second write or as above, if they differ.
In my testing, I stayed with a 16 byte, aligned, segment.

This is my testing with MaxForth V5.2 in interactive
hex entry mode:
Where: FLERASE will erase an 8K sector containing a given address
Z compares SECTOR to flash and prints the differences
SECTOR is a 512 byte buffer
COM and READY are command/response buffers
IAP takes a command buffer and returns it as a result buffer

3DC00 FLERASE OK ( erase 8K sector )
Z 3DC00 3DC04 3DC10 3DC14 3DC18 OK ( buffer has differences )
A55B SECTOR 10 + ! OK ( alter some buffer locations )
FFFFFFFF SECTOR 14 + ! OK
Z 3DC00 3DC04 3DC10 3DC18 OK ( less differences )
32 READY ! READY IAP ? 33 COM ! COM IAP ? Z 0 0 OK ( first write is ok )
A558 SECTOR 10 + ! Z 3DC10 OK ( change buffer again )
32 READY ! READY IAP ? 33 COM ! COM IAP ? Z 0 0 OK ( second write is ok )
FDP @ SECTOR 14 + ! Z 3DC14 OK ( change buffer again )
32 READY ! READY IAP ? 33 COM ! COM IAP ? Z 0 0 3DC18 OK ( third write fails )

The third write failed at a location that I wasn't even
changing (0x 3DC18).

I like the flash on the 6812 where they have two separate flash
banks with different write widths. The smaller one has a write
width of 4 bytes so if you need to write 32 bit values in flash
you use the smaller flash. If you can write in large blocks,
you use the larger flash.

Rob



--- In , "chazeltopman" <rob@n...> wrote:
> I've received an anonymous reply that addresses the
> flash writing limitations:
>
> : The flash can not be used '32 bit word' wise.
> : You could try to write 16 bytes at once (4x 32 bit word),
> : but the number of partial writes per 512 bytes (the normal
> : size) is limited (I don't believe this number is specified).
> :
> : Note the '16 byte'data should be properly aligned on 16 byte
> : multiples (but again the number of 'partial write'is limited
> : .. let's say .. 16 times or so :-) ).

After doing some more experimenting, I believe I have found the
happy compromise. If all the bytes in a 16 byte aligned sector are
0xFFFFFFFF, then one or more of them can be changed, but only
all at once. This is done with the write to flash IAP command.
Calling the flash IAP command multiple times with the same
section, can be done without error (I tried it 1000s of times
with zero errors). Putting these two lemmata together gives
me my flash management algorithm.

As I write values to flash, I do so on 16 byte boundaries. So
if I'm only writing 32-bits, I waste 12 bytes or 75%. But this
wastage can be reduced to 0% if I cache four 32 bit values and
then write them out at the same time to an empty 16 byte
section. This solves one problem and the dumb algorithm
solves the other. This worked on both the 8K and 64K sectors.

Onward.

Rob


I read the postings under the the "Flash fails to write..." topic,
but have problems following along and/or reproducing it.

My Goal:
to log single variables into flash occasionally, with minimum loss of
overhead (unused Flash space). Typically two 32bit values get stored
at the time, the first is an ID for the variable, the second is the
current value of that variable. When the current value of a variable
with a certain ID is needed, a backward search is started from the
end of the Flash sector downwards - if ID is found, the value behind
it is the last written value of that variable. Summary of thread so far and new questions from me:
1.) As stated in this thread, minimum write segment size on LPC is
512 bytes (per datasheet), so if just a few bytes are stored, a big
overhead occurs.

2.) First suggested work-a-round was to read a 512-byte segment, add
the new variables and write it back. I assume as long as the only bit
changes made are erasing bits, such a re-write can be performed
without a previous sector erase.
Correct?

3.) "Someone" came up with a 16byte boundary
I tried using a 16byte size instead of 512 when calling the IAP
routines, that results in a "COUNT_ERROR" reported back. Contents of
Flash did not change.

So how and where can I use this 16byte write? Or does this only apply
together with 2.)?
In other words:
a) read 512 bytes segment
b) pick a block of 16 bytes all set to FF
c) change data in block
d) write segment back (without erase)
?

TIA,

Peter




I have had extensive experience with the ARM flash storage on the
LPC2106 and LPC2129 forms and can pass along a few pieces of information
that might be helpful.

For the reprogramming algorithm with random access to flash storing a
32-bit aligned word where:

n - 32 bit number to store
a - address in flash to store n at
al - a aligned to a lowerbound 16 byte region: al = ((a+15)&~15)

if the 16 bytes from al are all 0xFF then you only need to modify
the segment with a read, modify and write back. If any of the 16
bytes are not 0xFF, then the sector must be copied out, modified,
flash sector erased and then written back.

To modify a segment (512 bytes), you'll need a temporary buffer
space to hold the data. The flash segment address should be on
a 512 byte boundary like the 16 byte one above.

To modify a sector (2K or 64K), you'll need a bigger buffer. On
the LPC2129, two of the flash sectors are 64K and the onboard RAM
is only 16K so it is not possible to do it this way (but you could
ping pong the two with incremental writes and have a safe backup
mechanism since you'd write before erase). The 2K sector can be
dealt with in the same manner as the 512 byte segment with an added
erase command thrown in which will add 400msec to the sequence.

So if you always pick an unwritten 16 byte aligned chunk of flash,
then you won't hav to do any expensive erasing on the fly. And
then how much you can buffer up to 16 bytes before writing will
determine your usage efficiency.

Now a word to the wary. Some early chips contain a bug in the erase
algorithm in the bootloader which causes the IAP call to not return
sometimes requiring a restart of the micro. This can be reproduced
by alternately writing and erasing a sector of flash. At some point
it hangs. I sent off an email with the details of my tests to
Philips and got a positive response where they acknowledged the
problem and replaced all the chips we had.

Here are the parts that we are currently having problem with:

Part # : LPC2106B-CC0057-TP323B
Bootloader Version 1.3

Part#: LPC2129FBD64-CC4761.00102-TP0404AY
Bootloader Version 1.6

Philip's response:
We have been experiencing difficulties with the flash array
that are similar to the problem you have described. This problem is
fixed (by modifying the bootloader) in later versions of the device.
At what stage of development are you? If you would require new
samples I can send them to you. Also, please give me the complete
part markings and the bootloader version. Previous posting:
>I read the postings under the the "Flash fails to write..." topic,
>but have problems following along and/or reproducing it.
>
>My Goal:
>to log single variables into flash occasionally, with minimum loss of
>overhead (unused Flash space). Typically two 32bit values get stored
>at the time, the first is an ID for the variable, the second is the
>current value of that variable. When the current value of a variable
>with a certain ID is needed, a backward search is started from the
>end of the Flash sector downwards - if ID is found, the value behind
>it is the last written value of that variable. >Summary of thread so far and new questions from me:
>1.) As stated in this thread, minimum write segment size on LPC is
>512 bytes (per datasheet), so if just a few bytes are stored, a big
>overhead occurs.
>
>2.) First suggested work-a-round was to read a 512-byte segment, add
>the new variables and write it back. I assume as long as the only bit
>changes made are erasing bits, such a re-write can be performed
>without a previous sector erase.
>Correct?

No this will cause other bits to flip unpredictably.

>
>3.) "Someone" came up with a 16byte boundary
>I tried using a 16byte size instead of 512 when calling the IAP
>routines, that results in a "COUNT_ERROR" reported back. Contents of
>Flash did not change.

Use proper alignment and criteria as mentioned above and it will work.

>
>So how and where can I use this 16byte write? Or does this only apply
>together with 2.)?
>In other words:
>a) read 512 bytes segment
>b) pick a block of 16 bytes all set to FF
>c) change data in block
>d) write segment back (without erase)
>?

and note the alignment to boundaries as per above.

Rob




--- In , Rob Chapman <rob@n...> wrote:
> Now a word to the wary. Some early chips contain a bug in the erase
> algorithm in the bootloader which causes the IAP call to not return
> sometimes requiring a restart of the micro. This can be reproduced
> by alternately writing and erasing a sector of flash. At some point
> it hangs. I sent off an email with the details of my tests to
> Philips and got a positive response where they acknowledged the
> problem and replaced all the chips we had.
>
> Here are the parts that we are currently having problem with:
>
> Part # : LPC2106B-CC0057-TP323B
> Bootloader Version 1.3
>
> Part#: LPC2129FBD64-CC4761.00102-TP0404AY
> Bootloader Version 1.6
>
> Philip's response:
> We have been experiencing difficulties with the flash array
> that are similar to the problem you have described. This problem is
> fixed (by modifying the bootloader) in later versions of the device.
> At what stage of development are you? If you would require new
> samples I can send them to you. Also, please give me the complete
> part markings and the bootloader version.

Thanks for the info! I'm trying to figure out why when I erase then write to flash, the MCU
just dies. We exactly have the same 2106 part you mentioned. Anyways, do you have the
BootLoader version that is supposed to have the fix? Thanks.

-John G-



>--- In , Rob Chapman <rob@n...> wrote:
>> Now a word to the wary. Some early chips contain a bug in the erase
>> algorithm in the bootloader which causes the IAP call to not return
>> sometimes requiring a restart of the micro. This can be reproduced
>> by alternately writing and erasing a sector of flash. At some point
>> it hangs. I sent off an email with the details of my tests to
>> Philips and got a positive response where they acknowledged the
>> problem and replaced all the chips we had.
>>
>> Here are the parts that we are currently having problem with:
>>
>> Part # : LPC2106B-CC0057-TP323B
>> Bootloader Version 1.3
>>
>> Part#: LPC2129FBD64-CC4761.00102-TP0404AY
>> Bootloader Version 1.6
>>
>> Philip's response:
>> We have been experiencing difficulties with the flash array
>> that are similar to the problem you have described. This problem is
>> fixed (by modifying the bootloader) in later versions of the device.
>> At what stage of development are you? If you would require new
>> samples I can send them to you. Also, please give me the complete
>> part markings and the bootloader version.
>
>Thanks for the info! I'm trying to figure out why when I erase then
>write to flash, the MCU
>just dies. We exactly have the same 2106 part you mentioned.
>Anyways, do you have the
>BootLoader version that is supposed to have the fix? Thanks.

The guy that builds the boards for me is getting the replacement
chips but I haven't got any new boards yet to verify. As far as
I know, we'll have to peal, toss and replace the micros on the
boards we've already made (we've had one board in production since
March). I don't know if the bootloader can be replaced.

Rob




--- In , Rob Chapman <rob@n...> wrote:
> >--- In , Rob Chapman <rob@n...> wrote:
> >> Now a word to the wary. Some early chips contain a bug in the erase
> >> algorithm in the bootloader which causes the IAP call to not return
> >> sometimes requiring a restart of the micro. This can be reproduced
> >> by alternately writing and erasing a sector of flash. At some point
> >> it hangs. I sent off an email with the details of my tests to
> >> Philips and got a positive response where they acknowledged the
> >> problem and replaced all the chips we had.
> >>
> >> Here are the parts that we are currently having problem with:
> >>
> >> Part # : LPC2106B-CC0057-TP323B
> >> Bootloader Version 1.3
> >>
> >> Part#: LPC2129FBD64-CC4761.00102-TP0404AY
> >> Bootloader Version 1.6
> >>
> >> Philip's response:
> >> We have been experiencing difficulties with the flash array
> >> that are similar to the problem you have described. This problem is
> >> fixed (by modifying the bootloader) in later versions of the device.
> >> At what stage of development are you? If you would require new
> >> samples I can send them to you. Also, please give me the complete
> >> part markings and the bootloader version.
> >
> >Thanks for the info! I'm trying to figure out why when I erase then
> >write to flash, the MCU
> >just dies. We exactly have the same 2106 part you mentioned.
> >Anyways, do you have the
> >BootLoader version that is supposed to have the fix? Thanks.
>
> The guy that builds the boards for me is getting the replacement
> chips but I haven't got any new boards yet to verify. As far as
> I know, we'll have to peal, toss and replace the micros on the
> boards we've already made (we've had one board in production since
> March). I don't know if the bootloader can be replaced.
>
> Rob

I was hoping you already tried the replacement chips and check the bootloader version.
Anyway, we're in the same predicament.

-John G-