EmbeddedRelated.com
Forums

interrupt-code execution during flash-erase.

Started by reym...@... March 6, 2006
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


Beginning Microcontrollers with the MSP430

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


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


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


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


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


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


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

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
>





--- 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)