Dear all! Has anyone ever encountered something like this: (or even has a workaround...) Erasing a flash segment (0x1000...0x103F) taks approx. 15 ms. During this time the code execution is halted or rather goes into an infinite loop as the flash hardware returns 0x3FFF on any fetch from the core. It is possible to interrup the erasure and execute interrupt code from flash. (FCTL1.EEI) In this case the interrupt code is correctly run but when this code tries to retrieve a constant from flash (e.g. mow.b. @R14, R14 with 0xFFD2 in R14) I do not get the true value into R14 but 0x00 instead as long as the erasure is pending. Any help appreciated. regards Dirk
interrupt-code execution during flash-erase.
Started by ●March 6, 2006
Reply by ●March 6, 20062006-03-06
When executing code from flash you most certainly can't do this as all
cpu operation is suspended, and the flash cycle cannot be interrupted.
When executing the flash write/erase from RAM it is possible to also
have the CPU read and write RAM, but it still cannot read/write FLASH.
On entering a flash write/erase operation all interrupts should be
disabled. This creates a problem if your interrupts are more frequent
than the flash erae time, which is 10124usecs for segment erase at
476kHz. So the best way to tackle this is to increase your flash clk
frequency to the maximum permissible, and, if you still have an
interrupt clashing problem I suggest trying to delay your flash
operations until the processor can be expected to hit an idle sequence,
or to predict their overflow or need for erasure ahead of time and to
p[erhaps do this if possible during a power up cycle.
For example if you use flash as a data logger and loop back once
allocated memory is filled you might check the next empty spot pointer
at power on (either by prestored or by ca;lculation) and, if the
available space is too low erase the next available segment during the
POR so it is ready when needed.
other than that no work around I'm aware of.
Cheers
Al
reymannd@reym... wrote:
>Dear all!
>
>Has anyone ever encountered something like this:
>(or even has a workaround...)
>
>Erasing a flash segment (0x1000...0x103F) taks approx. 15 ms.
>During this time the code execution is halted or rather goes into an
>infinite
>loop as the flash hardware returns 0x3FFF on any fetch from the core.
>
>It is possible to interrup the erasure and execute interrupt code from
>flash.
>(FCTL1.EEI)
>
>In this case the interrupt code is correctly run but when this code tries
>to retrieve
>a constant from flash (e.g. mow.b. @R14, R14 with 0xFFD2 in R14) I do
>not get
>the true value into R14 but 0x00 instead as long as the erasure is pending.
>
>
>Any help appreciated.
>
>regards
>Dirk
>
>
>
>.
>
>
>Yahoo! Groups Links
>
>
>
>
>
>
>
>
>
>
Reply by ●March 6, 20062006-03-06
Onestone wrote:
>When executing code from flash you most certainly
can't do this as all
Sorry Al - Yes, I can!
MSP430F21x1 User Guide ch 5.3.4 page 5-16
The program is run from flash only.
The erase-cycle runs at leat 10 ms, as you stated correctly.
When an interrupt occurs, the erase-cycle is interrupted
and the interrupt service routine can be executed from flash.
Afterwards the erase-cycle is continued.
This works - I've tried it.
But now, for some strange reason when this interrupt service
routine fetches a value from flash it gets back 0x00 as long as
the erase-cyle is pending.
regards
Dirk
Reply by ●March 6, 20062006-03-06
OK you didn't say you were using the 21xx, which has aunique Flash
access system and operates slightly differently than the older 1xx and
4xx parts, and even the 20xx parts, in that it implements both an exit
on interrupt and an emergency exit on interrupt function. As of 10
minutes ago I still couldn't find the 21xx speicifc user guide if it
exists, and had a hell of a time finding the 2xxx FUG. Ti have now made
their website inscrutable it seems, no simple tab for 'DOCUMENTS'
anymore.
Okay. I assume you are disabling WDT, and enabling EEI and GIE with
EEIEX set to 0, and that nested interrupts aren't enabled? If EEIEX is
set then an interrupt will set the FAIL flag, the interrupt occurs
immediately, unlike when EEI is the cause, where it is only tested every
32Fftg cycles, so the state of the flash being erased or written at the
time of an EEIEX will be unpredictable. There is no pertinent errata, so
the onlt thing that stands out is GIE enabled in your ISR or EEI and
EEIEX enabled together and you're possibly attempting to read the
segment that was aborted. This is only a stab, since the FUG does not
say what happens to the aborted segment or word that was being addressed.
Cheers
Al
The second para on this page clearly states that
reymannd@reym... wrote:
>Onestone wrote:
>
>
>
>>When executing code from flash you most certainly can't do this as
all
>>
>>
>
>Sorry Al - Yes, I can!
>MSP430F21x1 User Guide ch 5.3.4 page 5-16
>
>The program is run from flash only.
>The erase-cycle runs at leat 10 ms, as you stated correctly.
>When an interrupt occurs, the erase-cycle is interrupted
>and the interrupt service routine can be executed from flash.
>Afterwards the erase-cycle is continued.
>
>This works - I've tried it.
>But now, for some strange reason when this interrupt service
>routine fetches a value from flash it gets back 0x00 as long as
>the erase-cyle is pending.
>
>
>regards
>Dirk
>
>
>
>.
>
>
>Yahoo! Groups Links
>
>
>
>
>
>
>
>
>
>
Reply by ●March 6, 20062006-03-06
Hi Al! now we're going into the same direction. :-) Also thanks for the stab, but I'm affraid the truth is a little more difficult. Anyway, maybe somebody else has followed the dicsussion and has a good idea. To gain a deeper insight: - The main program, which accesses the info flash at 0x1000 is erasing and writing the appropriate range without problems. This works fine, is tested and verified and the contents of the flash memory are exactly as exepcted at any time - The interrupt routine (TIMERA) is invoked every 1 ms. It actually is invoked always and reliably as expected. The routine has nothing to do with info flash and does not access the range at 0x1000 at any time. - The interrupt route tries to read a string from programm-flash, somewhere at 0xFFC2. Therefore R14 contains the pointer and is also used to read back the value from flash: mow.b. @R14, R14. So R14 should afterwards contain the content of the location that R14 pointed to. But what happens... Cycle FlashEraseActive R14 1 * 0x00 2 * 0x00 3 * 0x00 4 * 0x00 5 * 0x00 6 * 0x00 7 * 0x00 8 * 0x00 9 * 0x00 10 * 0x00 11 * 0x00 12 * 0x00 13 * 0x00 14 0x77 15 0x77 16 0x77 regards Dirk
Reply by ●March 6, 20062006-03-06
I'm no expert with the 21xx, you have me there by a country mile,
since
mine haven't even arrived here yet, but from your description of your
problem it would seem to be a software issue, since you say that at one
time you had it working, and you should be able to assume that the
internal hardware of the micro hasn't changed. I presume you've looked
at the usual suspects, corruption of R14 in the ISR, GIE set
inadvertently. Now one thing that strikes me is the number of interrupts
you will get during each flash erase cycle, and occuring at every
32Fftgclk. You originally said that your flash erase took 15msecs, so
perhaps you were using a slower Fftgclk. In that case 15msecs gives an
Fftgclk of around 320kHz. What are your CPU clock frequencies like, and
how long does the ISR take to execute. I presume it is very fast, just
an incrment and store deal.. When I see data repeating and showing a
change in the middle as yours does, ie 00H to 77H, and there being
interrupts every 1msec, and the nominal erase time is 15msecs or so, I
suspect that the 77H is what is read AFTER the segment erase, or, if
multi segment, after the first segment erase. How is the data stored in
flash in the first place? Anyway, thought trail, perhaps the change of
data is a clue. I would set up a single segment erase pass first and
check busy in the ISR to flag those readings taken during the erase.
Anyway, best of luck, you have the tools I don't, I would be keen to
here the solution when you get there.
cheers
Al
reymannd@reym... wrote:
>Hi Al!
>
>now we're going into the same direction. :-)
>Also thanks for the stab, but I'm affraid the truth is a little more
>difficult.
>
>Anyway, maybe somebody else has followed the dicsussion and has a good
>idea.
>
>
>To gain a deeper insight:
>
>- The main program, which accesses the info flash at 0x1000 is erasing and
>writing the appropriate
>range without problems. This works fine, is tested and verified and the
>contents of the flash memory
>are exactly as exepcted at any time
>
>- The interrupt routine (TIMERA) is invoked every 1 ms. It actually is
>invoked always and reliably
>as expected. The routine has nothing to do with info flash and does not
>access the range at 0x1000
>at any time.
>
>- The interrupt route tries to read a string from programm-flash, somewhere
>at 0xFFC2.
>Therefore R14 contains the pointer and is also used to read back the value
>from flash:
>mow.b. @R14, R14. So R14 should afterwards contain the content of the
>location
>that R14 pointed to.
>
>But what happens...
>
>Cycle FlashEraseActive R14
> 1 * 0x00
> 2 * 0x00
> 3 * 0x00
> 4 * 0x00
> 5 * 0x00
> 6 * 0x00
> 7 * 0x00
> 8 * 0x00
> 9 * 0x00
> 10 * 0x00
> 11 * 0x00
> 12 * 0x00
> 13 * 0x00
> 14 0x77
> 15 0x77
> 16 0x77
>
>
>regards
>Dirk
>
>
>
>.
>
>
>Yahoo! Groups Links
>
>
>
>
>
>
>
>
>
>
Reply by ●March 6, 20062006-03-06
Whoops. missed the flash erase active '*' symbol. This is
definitely the
big clue I reckon, Do you have any spare RAM? How is R14 being reloaded
with the address of the next byte? Rx,Rx can be a bear trap if you're
not careful, I try to use Rx,Ry. In your case something like:-
mov.b @R14+,0(R15)
inc R15
Obviously this presumes R14 and R15 are dedicated, and some overflow
logic exists.
Just as a test can you try something like:_
mov.w R14,0(R15)
inc R15
before your mov.b @R14,R14. Where R15 is dedicated and set to point to a
RAM buffer immediately prior to entering the erase procedure. Then
breakpoint immediately after the erase procedure, or after N transfers.
The data change may be a furfy, but it looks too obvious not to pursue
for now, there areno other clues that I can see.
Cheers again
Al
reymannd@reym... wrote:
>Hi Al!
>
>now we're going into the same direction. :-)
>Also thanks for the stab, but I'm affraid the truth is a little more
>difficult.
>
>Anyway, maybe somebody else has followed the dicsussion and has a good
>idea.
>
>
>To gain a deeper insight:
>
>- The main program, which accesses the info flash at 0x1000 is erasing and
>writing the appropriate
>range without problems. This works fine, is tested and verified and the
>contents of the flash memory
>are exactly as exepcted at any time
>
>- The interrupt routine (TIMERA) is invoked every 1 ms. It actually is
>invoked always and reliably
>as expected. The routine has nothing to do with info flash and does not
>access the range at 0x1000
>at any time.
>
>- The interrupt route tries to read a string from programm-flash, somewhere
>at 0xFFC2.
>Therefore R14 contains the pointer and is also used to read back the value
>from flash:
>mow.b. @R14, R14. So R14 should afterwards contain the content of the
>location
>that R14 pointed to.
>
>But what happens...
>
>Cycle FlashEraseActive R14
> 1 * 0x00
> 2 * 0x00
> 3 * 0x00
> 4 * 0x00
> 5 * 0x00
> 6 * 0x00
> 7 * 0x00
> 8 * 0x00
> 9 * 0x00
> 10 * 0x00
> 11 * 0x00
> 12 * 0x00
> 13 * 0x00
> 14 0x77
> 15 0x77
> 16 0x77
>
>
>regards
>Dirk
>
>
>
>.
>
>
>Yahoo! Groups Links
>
>
>
>
>
>
>
>
>
>
Reply by ●March 7, 20062006-03-07
Wolfgang, > I wouldn't be surprised if this were a CPU bug - automatic flash > erasure abort is a new feature. > There is also this nasty little CPU bug called "CPU 6" in the > MSP430F21x1 (see errata sheet slaz020.pdf - BTW: is your > compiler/assembler aware of this bug?). It affects ADD instructions > with indirect addressing, like ADD @R14,R14, executed after RET or > RETI. Perhaps not only ADD after RET .... just a wild idea. > > Did you ask TI about that phenomenon? Word from TI is that the next batch of 21x1s will have this bug corrected. -- Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk CrossWorks for MSP430, ARM, AVR and now MAXQ processors
Reply by ●March 7, 20062006-03-07
Hi Dirk, so you're reading 0x00 from program flash in an ISR while info flash erasure is suspended? But the code (which is also in program flash) executes ok in the ISR? Did you try a different instruction sequence to read the string (as Al suggested)? I wouldn't be surprised if this were a CPU bug - automatic flash erasure abort is a new feature. There is also this nasty little CPU bug called "CPU 6" in the MSP430F21x1 (see errata sheet slaz020.pdf - BTW: is your compiler/assembler aware of this bug?). It affects ADD instructions with indirect addressing, like ADD @R14,R14, executed after RET or RETI. Perhaps not only ADD after RET .... just a wild idea. Did you ask TI about that phenomenon? Regards, Wolfgang "Never argue with an idiot. They drag you down to their level and then beat you with experience." (Dilbert) --- In msp430@msp4..., reymannd@... wrote: > > Hi Al! > > now we're going into the same direction. :-) > Also thanks for the stab, but I'm affraid the truth is a little more > difficult. > > Anyway, maybe somebody else has followed the dicsussion and has a good > idea. > > > To gain a deeper insight: > > - The main program, which accesses the info flash at 0x1000 is erasing and > writing the appropriate > range without problems. This works fine, is tested and verified and the > contents of the flash memory > are exactly as exepcted at any time > > - The interrupt routine (TIMERA) is invoked every 1 ms. It actually is > invoked always and reliably > as expected. The routine has nothing to do with info flash and does not > access the range at 0x1000 > at any time. > > - The interrupt route tries to read a string from programm-flash, somewhere > at 0xFFC2. > Therefore R14 contains the pointer and is also used to read back the value > from flash: > mow.b. @R14, R14. So R14 should afterwards contain the content of the > location > that R14 pointed to. > > But what happens... > > Cycle FlashEraseActive R14 > 1 * 0x00 > 2 * 0x00 > 3 * 0x00 > 4 * 0x00 > 5 * 0x00 > 6 * 0x00 > 7 * 0x00 > 8 * 0x00 > 9 * 0x00 > 10 * 0x00 > 11 * 0x00 > 12 * 0x00 > 13 * 0x00 > 14 0x77 > 15 0x77 > 16 0x77 > > > regards > Dirk >
Reply by ●March 7, 20062006-03-07
--- In msp430@msp4..., "Paul Curtis" <plc@...> wrote: > > > There is also this nasty little CPU bug called "CPU 6" in the > > MSP430F21x1 (see errata sheet slaz020.pdf - BTW: is your > > compiler/assembler aware of this bug?). It affects ADD instructions > > with indirect addressing, like ADD @R14,R14, executed after RET or > > RETI. > > Word from TI is that the next batch of 21x1s will have this bug > corrected. Yes, TI told us it'll be fixed in rev E, but also that for the next few months we'd still get rev D from the distris. We made some prototypes with rev D MSP430F2121, and it's not sure that we'll get rev. E by the time we go into production, so we needed a workaround for this bug - and we got it from our compiler vendor within very short time :-) Wolfgang "Never argue with an idiot. They drag you down to their level and then beat you with experience." (Dilbert)