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