This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28027: C28x core interrupt service routine

Part Number: TMS320F28027

Dear C2000 expert,

I used C function as ISR entrance, and would like to call assembly function in C ISR. But I found that if I used ASP instruction at the beginning of assembly function, and NASP at the end of it, then the PC can't be restored to the value that before interrupting. Can you please let me know why? And what is the limitation of using ASP/NASP instruction?

Here is what my code looks like:

1. C function for ISR entrance:

//
// epwm1_timer_isr - Interrupt routines uses in this example
//
__interrupt void
epwm1_timer_isr(void)
{
     EPwm1TimerIntCount++;

     assembly_func();
     //
     // Clear INT flag for this timer
     //   
     EPwm1Regs.ETCLR.bit.INT = 1;

     //
     // Acknowledge this interrupt to receive more interrupts from group 3
     //
     PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}

2. Assembly function code: if the ASP and NASP instructions are in the function, then PC can't be restored into correct value after ISR execute completely. 

; label to _assembly_func function
.def _assembly_func

.text

_assembly_func:
;context save
ASP
PUSH AR1H:AR0H
PUSH XAR2
PUSH XAR3
PUSH XAR4
PUSH XAR5
PUSH XAR6
PUSH XAR7
PUSH XT


;-----------------------
; full context restore
POP XT
POP XAR7
POP XAR6
POP XAR5
POP XAR4
POP XAR3
POP XAR2
POP AR1H:AR0H
NASP
LRETR ;Long Return Using RPC

Regards,

Jack

  • Hello,
    I am writing to let you know that a C2000 team member has been assigned to this post and should be answering shortly.

    Regards
    Baskaran
  • Jack,
    You do not need to use ASP or NASP in your assembly function. Those instructions are really meant for interrupts, to ensure the even alignment of the stack when the interrupt is taken. The C compiler always maintains the stack pointer even word aligned, so you are safe in leaving those instructions out of the assembly function.
    It's not explicitly spelled out in the documentation, but what's happening, as you correctly surmised, is that the ASP at the beginning of your assembly function is over-writing the SPA bit in the ST1 register which was previously written by the ASP at the start of the ISR. This potentially the wrong value is corrupting the NASP at the end of the ISR.
    Comment out the ASP and NASP and you should be fine.
    Regards,
    Richard
  • Jack,

    I wanted to add that by using

    PUSH AR0H:AR1H

    ...you are only protecting the upper 16-bits of those registers. This is normally done in an ISR because the automatic interrupt context save takes care of the low 16-bits of both registers. In a function call from C, the compiler will protect XAR0 anyway, but you'll need to protect XAR1 (if you use it) with:

    PUSH XAR1

    Similarly on context restore.  See section 7.2 of the C compiler user's guide for details on which registers need to be protected on an assembly function call.

    Regards,

    Richard

  • Hi Richard,

    Thanks for your clear answer. Can you please help let me know why does the stack need even address aligned in ISR?

    Jack
  • Hi Richard,

    One more question, what condition that the SP should be even address aligned? I mean that what condition we have to use ASP instruction? Thanks...

    Regards,
    Jack
  • Hi Jack,

    On C28x, any 32-bit reads or writes to memory are even word aligned. If you write a 32-bit value to an odd memory address the operation will take two cycles. For example, in your context save you are pushing sequentially several 32-bit registers onto the stack, so it's much more efficient if you start on an even word boundary.

    You should use the ASP / NASP combination in an ISR to ensure the stack is aligned. Although the compiler maintains even word alignment, interrupts are asynchronous so we can't be sure what value SP has when the interrupt is taken. The ST1 register is protected by the automatic context save on interrupt, so the SPA bit is always restored correctly when the ISR ends. What we can't do is manually put an ASP / NASP in a C callable assembly function because as you found the SPA value is over-written.

    So, to answer your last question, you would only use ASP / NASP if you were writing an ISR in assembly.

    Regards,

    Richard
  • Hi Richard,

    It's very clear for me. Thanks for your great support.

    Regards,

    Jack