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