At the cost of more of my hair, I have found another possible bug in the
compiler.
When using Timer_A IRQ, the compiler doesn't save any registers it might
use for calculations.  Here is a listing of my Timer_A ISR:
00001b76 <TimerACC0IRQ>:

volatile unsigned long int lastcc;
/***********************************************************************
*******
      Timer_A Capture Compare Interrupt Service Routine (CCIFG0):
************************************************************************
******/
interrupt (TIMERA0_VECTOR) TimerACC0IRQ( void )
{

    if ( TACTL & TAIFG )                // Check for overflow
    1b76:       92 b3 60 01     bit     #1,     &0x0160 ;r3 As==01
    1b7a:       13 24           jz      $+40            ;abs 0x1ba2
        {
        count8m = 65535u - lastcc + TACCR0;
    1b7c:       1f 42 72 01     mov     &0x0172,r15     ;0x0172
    1b80:       0e 4f           mov     r15,    r14     ;
    1b82:       0f 43           clr     r15             ;
    1b84:       1c 42 04 02     mov     &0x0204,r12     ;0x0204
    1b88:       1d 42 06 02     mov     &0x0206,r13     ;0x0206
    1b8c:       0e 8c           sub     r12,    r14     ;
    1b8e:       0f 7d           subc    r13,    r15     ;
    1b90:       3e 53           add     #-1,    r14     ;r3 As==11
    1b92:       0f 63           adc     r15             ;
    1b94:       82 4e 00 02     mov     r14,    &0x0200 ;
    1b98:       82 4f 02 02     mov     r15,    &0x0202 ;
        TACTL &= ~TAIFG;                // Clear Timer_A Interrupt flag
(overflow bit)
    1b9c:       92 c3 60 01     bic     #1,     &0x0160 ;r3 As==01
    1ba0:       0e 3c           jmp     $+30            ;abs 0x1bbe
        }
    else
        count8m = TACCR0 - lastcc;
    1ba2:       1f 42 72 01     mov     &0x0172,r15     ;0x0172
    1ba6:       0e 4f           mov     r15,    r14     ;
    1ba8:       0f 43           clr     r15             ;
    1baa:       1c 42 04 02     mov     &0x0204,r12     ;0x0204
    1bae:       1d 42 06 02     mov     &0x0206,r13     ;0x0206
    1bb2:       0e 8c           sub     r12,    r14     ;
    1bb4:       0f 7d           subc    r13,    r15     ;
    1bb6:       82 4e 00 02     mov     r14,    &0x0200 ;
    1bba:       82 4f 02 02     mov     r15,    &0x0202 ;
    lastcc = TACCR0;
    1bbe:       1f 42 72 01     mov     &0x0172,r15     ;0x0172
    1bc2:       0e 4f           mov     r15,    r14     ;
    1bc4:       0f 43           clr     r15             ;
    1bc6:       82 4e 04 02     mov     r14,    &0x0204 ;
    1bca:       82 4f 06 02     mov     r15,    &0x0206 ;

    TACCTL0 &= ~CCIFG;                // Clear CCIFG Interrupt flag
    1bce:       92 c3 62 01     bic     #1,     &0x0162 ;r3 As==01
    __asm__( "reti" );
    1bd2:       00 13           reti                    

00001bd4 <BasicTimerIRQ>:
}

It would appear that this function is acting as if I had the "naked"
property set (which I don't).  This is easily solved by manually adding
the push and pop statements that account for the registers used.  Here's
my solution:
    __asm__( "push r15" );
    __asm__( "push r14" );
    __asm__( "push r13" );
    __asm__( "push r12" );
/******* Body of ISR *******/
    __asm__( "pop  r12" );
    __asm__( "pop  r13" );
    __asm__( "pop  r14" );
    __asm__( "pop  r15" );

This works, but obviously, I shouldn't have to do this.
Cheers
-Mark Stokes


Reply via email to