EmbeddedRelated.com
Forums

MSP430F149 Interrupt Handling

Started by soon yan bo February 2, 2008
As I said, I got the "free" KickStart from TI.
I found that it compiles "LPM0_EXIT" into "bic.w #0x10,0(SP)"
It simply clears CPUOFF.
SCG1, SCG0, OSCOFF, etc, are unchanged.

--- In m..., jonk@... wrote:
>
> Let me add a comment to what I just wrote, namely:
>
> > I take it that you mean that SCG1 and SCG0 and OSCOFF are 0?
> > But isn't that exactly what it takes to get INTO LPM0 mode??
> > If so, the return from interrupt will do what I feared and
> > pointed out, earlier.
>
> Also, CPUOFF is '1', I should have added. It's been my
> experience with LPM0 that it disables the CPU. Isn't that
> right?
>
> Jon
>

Beginning Microcontrollers with the MSP430

> --- In m..., jonk@... wrote:
>>
>> Let me add a comment to what I just wrote, namely:
>>
>> > I take it that you mean that SCG1 and SCG0 and OSCOFF are 0?
>> > But isn't that exactly what it takes to get INTO LPM0 mode??
>> > If so, the return from interrupt will do what I feared and
>> > pointed out, earlier.
>>
>> Also, CPUOFF is '1', I should have added. It's been my
>> experience with LPM0 that it disables the CPU. Isn't that
>> right?
>
> As I said, I got the "free" KickStart from TI.
> I found that it compiles "LPM0_EXIT" into "bic.w #0x10,0(SP)"
> It simply clears CPUOFF.
> SCG1, SCG0, OSCOFF, etc, are unchanged.

Well, I didn't gather that's what you said, when you wrote, "I found that
LPM0_EXIT actually ***clears*** the LPM0 bits of the saved SR in the
stack." But thanks to your kick here, I went and looked at the
instruction generated, too. And it just clears one bit (bic #0x10), which
is indeed just the CPUOFF bit.

Okay. So the last thing done in the interrupt routine is to _enable_ the
cpu and to leave the rest of the LPM mode bits on the stack alone. Which
should leave the cpu operational _after_ the return.

However, your forcing me to go look at the actual assembly generation
produced another effect. The posted code did not have a #pragma such as
this:

#pragma vector= TIMERA1_VECTOR

before the interrupt code, itself. As a result, the compiler doesn't
place a vector pointer. And because it doesn't do that, the interrupt
code itself doesn't appear in the resulting binary, so far as I can tell.

Also, now that I'm looking closer at the code than before, I also notice
that the original poster sets up the timer bits in TACTL all at once.
It's been my practice to first reset it with the TACLR, using MC_0, then
set up CTL0 and CCR0, and then go back and set TACTL with, say, MC_1 after
that. So I'd modify the poster's code on that part to say:

TACTL= MC_0 | TASSEL_1 | ID_0 | TACLR;
TACCTL0= CM_0 | CCIS_2 | SCS | OUTMOD_1 | CCIE;
TACCR0= 19999;
TACTL= MC_1 | TASSEL_1 | ID_0;

Something like that, instead. Not sure if ID_0 is the desired one, right
now. But whatever it should be, I'd include it, too, as shown above.

But the #pragma is vital.

Jon
When I wrote, "I found that LPM0_EXIT actually ***clears*** the LPM0
bits of the saved SR in the stack." I was also a victim of the header
file that says:

#define LPM0_bits (CPUOFF)
#define LPM0_EXIT _BIC_SR_IRQ(LPM0_bits)

Sorry for that!
> TACTL= MC_0 | TASSEL_1 | ID_0 | TACLR;
> TACCTL0= CM_0 | CCIS_2 | SCS | OUTMOD_1 | CCIE;
> TACCR0= 19999;
> TACTL= MC_1 | TASSEL_1 | ID_0;

The OP used CCR0, so the above 19999 is only an example. Also, I
provided some examples for other facets of CTL0 above that I might use
instead of just setting it to CCIE.

Jon