Hi Mark,

How did you compile this? I have a project right now with a *huge* Timer_A0 interrupt service routine, that actually does most of the software's work. It gets a reti at the end without trouble, and handles all the registers properly.

I tried to extract the C lines from your post and made a file. I didn't see where count8m was defined, so I made it a global, like lastcc. If I compile this:


#include <signal.h>
#include <io.h>

volatile unsigned long int lastcc;
volatile unsigned long int count8m;

interrupt (TIMERA0_VECTOR) TimerACC0IRQ(void)
{
   if ( TACTL & TAIFG )                // Check for overflow
   {
       count8m = 65535u - lastcc + TACCR0;
       TACTL &= ~TAIFG;                // Clear Timer_A Interrupt flag
   }
   else
   {
       count8m = TACCR0 - lastcc;
   }
   lastcc = TACCR0;
   TACCTL0 &= ~CCIFG;                // Clear CCIFG Interrupt flag
}



with this command:

msp430-gcc -mmcu=msp430x435 -c -S -o mark.s mark.c

I get this:



   .file    "mark.c"
   .arch msp430x435

   .text
   .p2align 1,0
.global    TimerACC0IRQ
.global    vector_ffec
   .type    TimerACC0IRQ,@function
/***********************
* Interrupt Service Routine `TimerACC0IRQ' at 0xffec
***********************/
vector_ffec:
TimerACC0IRQ:
/* prologue: frame size = 0 */
.L__FrameSize_TimerACC0IRQ=0x0
.L__FrameOffset_TimerACC0IRQ=0xc
   push    r15
   push    r14
   push    r13
   push    r12
   push    r5
   push    r4
/* prologue end (size=6) */
   mov    &0x0160, r15
   and    #llo(1), r15
   jeq    .L2
   mov    &0x0172, r15
   mov    r15, r12
   clr    r13
   mov    &lastcc, r14
   mov    &lastcc+2, r15
   sub    r14, r12
   subc    r15, r13
   mov    r12, r14
   mov    r13, r15
   add    #llo(65535), r14
   addc    #lhi(65535), r15
   mov    r14, &count8m
   mov    r15, &count8m+2
   bic    #llo(1),&0x0160
   jmp    .L3
.L2:
   mov    &0x0172, r15
   mov    r15, r12
   clr    r13
   mov    &lastcc, r14
   mov    &lastcc+2, r15
   sub    r14, r12
   subc    r15, r13
   mov    r12, r14
   mov    r13, r15
   mov    r14, &count8m
   mov    r15, &count8m+2
.L3:
   mov    &0x0172, r15
   mov    r15, r14
   clr    r15
   mov    r14, &lastcc
   mov    r15, &lastcc+2
   bic    #llo(1),&0x0162
/* epilogue: frame size=0 */
   pop    r4
   pop    r5
   pop    r12
   pop    r13
   pop    r14
   pop    r15
   reti
/* epilogue end (size=7) */
/* function TimerACC0IRQ size 65 (52) */
.Lfe1:
   .size    TimerACC0IRQ,.Lfe1-TimerACC0IRQ
/********* End of function ******/

   .comm lastcc,4,2
   .comm count8m,4,2

/*********************************************************************
* File mark.c: code size: 65 words (0x41)
* incl. words in prologues: 6, epilogues: 7
*********************************************************************/

Since I believe you are using my installer, we should be building with the same version of mspgcc.

Regards,
Steve




Mark Stokes wrote:

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