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.

Jump to a label after a RETI

Other Parts Discussed in Thread: TMS320F28335

Hello,

There is my question :

From a pin interrupt (handle at power off) I want my micro enter in LPM3 to keep the RTC running.

To keep the maximal energy store in a SuperCap and have a running  RTC for several hours,  the time between Interrupt routine and   my low power mode function (configure all peripherals & pins) has to be as short as possible. 

The problem is after the ISR my program return to his previous task which has a heavy consumption of energy and my supercap become useless before go in LPM3. 

I don't know how to do this but I would like to modify the RETI of the ISR to go directly in my fuction low power mode (somewhat as using a goto instruction but in C).

 

Does someone know C langage tips to do that?

Thank you

 

Here is a part of my code : 

 

#pragma vector=PORT1_VECTOR

__interrupt void Port1_ISR (void)

{

if(P1IFG & P_ITAL){

POUT_ENPWR &= ~P_ENPWR;

P1IE  &= ~P_ITAL;                            // Interrupt disabled

P1IFG &= ~P_ITAL; 

GATW.Mode = POWER_OFF;

if (GATW.Sleep == 1){

LPM3_EXIT;

}

} 

 

 

while(1){

 

  switch(GATW.Mode)  {

        case TASK1:{

function1();  // These functions are not determinist, it could take more than 1 second

function2();

break;}

 

 case POWER_OFF:{

 

Low_power_Mode();  // I WANT JUMP HERE STRAIGHT AFTER THE RETI FROM PORT1_ISR

P1IES &= ~P_ITAL; // hi/low edge P1IFG &= ~P_ITAL; // IFG Cleared P1IE |= P_ITAL; // Interrupt enabled _BIS_SR(LPM3_bits + GIE); // LPM3, enable interrupts

 

break;}

}

 

  • Emilien BENHARD said:
    Does someone know C langage tips to do that?

    No.

    Interrupt functions are outside the scope of the C language, and jumping around in the code may lead to unpredictable behavior.

    However, an interrupt that leads to an LPM state can be done. But not in the way you think.

    Normally, when an ISR is entered, teh GIE bit is clear and this ISR cannot be interrupted. If precautions are tagen to avoid endless ISR loops and stack overflows, one may set teh GIE bit inside an ISR and allow further interrupts (even for the same ISR interrupting itself, one of the pitfalls) and then you may even enter LPM inside this ISR without ever returning to main. However, the logic to handle this and prevent endless recursions is quite complex.

    You surely have two different causes for entering and leaving LPM. Best case are two different ISRs, but even inside one it is possible.

    Some symbolic code here:

     

    volatile char inLPM = 0;

    ISR 'go into LPM':
    [...]handling of interrupt cause (IFG bits must be reset before proceeding)
    if(!inLPM)
    {
      deactivate hardware
      inLPM=1;
      _BIS_SR_register(LPM3_bits|GIE)
    }

    ISR 'reactivate device'
    if(inLPM)
    {
      inLPM=0;
      LPM3_EXIT();
    }

    After exiting LPM3 in the reactivate ISR (which might be the same as the 'go into LPM' ISR) code execution is continued in the previous instance of the 'go into LPM' ISR, which was suspended into LPM3 before. This ISR will then exit to main. However, if your main code might have problems with the temporarily deactivated hardware, you should also set a global 'bail_out' flag and implement a check for it into your main code, so it knows that the hardware was deactivated and maybe the expected program flow has been compromised (e.g. ADC conversions invalid, serial transmissions timed out or were interrupted mid-byte etc.)

    Or you never return to main at all, triggering e.g. a watchdog password violation when the device shall wakeup again, so the complete main is restarted. (of course your main code shoudl detect this by checking the WDTIFG bit, and reset it, so it doesn't re-init the RTC as if it were  real power_up).

  • Hi Jens-Michael

    Thank you for answer. I was surprised at start but it works!!

  • 730189 said:
    I was surprised at start but it works!!

    So you're no longer surprised? Good!. Once you understood how things work, you can start letting them work for you. That's the difference between engineer and user. :)

    Hmmm, that brings up an idea: the users guide should be renamed to engineers guide. An MSP user won't need it. :))

  • Hi ,
    I am interfacing MAX3109 with TMS320F28335 through MCBSP (as SPI). MAX 3109 asserts an interrupt for some events and that interrupt can only be cleared by reading Interrupt Status Register of MAX 3109.
    To read Interrupt Status Register, I am waiting for MCBSP receive flag and then read the DRR (Data Receive Register).
    At the ISR , I want to read Interrupt Status Register of MAX3109 to clear the interrupt. If I read Status Register at ISR it does not clear the interrupt. If I read the Status Register in main() it clears the interrupt.
    I can't understand what is happening ?
    Can you help me ?
  • Not sure why you attached your question to  this post as it has nothing to do with set LMP3_on_exit

    A ISR should not do function calls, so unless it's just a dummy reading by sending a single byte (or it triggers SPI ISR to continue sending 2-4 bytes)
    This ISR should trigger the SPI routine you have in main,
    as main should be sleeping in lmp0-3 mode the ISR simply clear LMPx_bits_on_exit (the opposite that the OP wanted)

  • Without knowing your code, we can't say what's wrong. But as Tony suspected, your function to clear the status register seems to be incompatible with being called from inside an ISR. Maybe it neds interrupts itself (which are disabled during execution of an ISR) or has other problems.
    In general, you should neve do anything inside an ISR that requires any kind of waiting. In this case, create a state machine and come back later (e.g. triggered by a timer). ISRs are not threads for parallel execution.

    The common solution is to set a flag inside the ISR that main() must read the status register, and then wake main. Main itself will check for any things to do when waking up from LPM and then perform the required actions.

**Attention** This is a public forum