NOT RETURNING FROM INTERRUPT

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

NOT RETURNING FROM INTERRUPT

1,293 Views
embitel
Contributor I

Hello everyone,

 

I am using a Minidragon plus2 with mixed C & assembly as shown in the book:
"Learning C by example" & have seemingly run into the max C code limit.

Using Codewarrior 5.1 with PE USB MULTILINK.

 

My code is as follows

 

The problem PC is jumping to ISR and after completing ISR, control is looping back to again ISR.

 

control is not retruning from interrupt.

 

I have seen stack frame in sigle step everything seems stacking.

 

Can someone please look the code and tell where is the problem in code.

 

Memory model is "banked".

 

#include <hidef.h>      /* common defines and macros */
//#include "derivative.h"      /* derivative-specific definitions */
#include "hcs12def.h"      /* common defines and macros */

 

 

//-------------------------------------------------------------------------------------------------------------------------------------------------
#pragma CODE_SEG NON_BANKED
//-------------------------------------------------------------------------------------------------------------------------------------------------
interrupt 20 void  SCI1_Isr (void)
{
 volatile unsigned char scicr2,scisr1;
 static unsigned char RxCnt=0;
 unsigned int i;
 scisr1 = SCI0SR1;
 scicr2 = SCI0CR2;
 
  i = SCI0DRL;

//transmit

 SCI0DRL = i;  //TRANSMIT 1
 
     PTM |= 0x10; //glowing led
    
    PTM |= 0x08; //glowing led
    
    PTM |= 0x20; //glowing led
}
//------------------------------------------------------------------------------------------------------------------------------------------------
#pragma CODE_SEG DEFAULT
//------------------------------------------------------------------------------------------------------------------------------------------------

 

#pragma CODE_SEG NON_BANKED
void main(void) {
  /* put your own code here */
  int ix;
  long ltmp;  

  unsigned int i;
  
    // initalize PLL - reset default is Oscillator clock
    // 8 MHz oscillator, PLL freq = 48 MHz, 24 MHz bus,
    //  divide by 16 for timer of 2/3 usec tic
    PLLCTL &= 0xBF;     // Turn off PLL so can change freq
    SYNR = 0x02;        // set PLL/ Bus freq to 48/ 24 MHz
    REFDV = 0x00;
    PLLCTL |= 0x40;     // Turn on PLL
    // wait for PLL lock
    while (!(CRGFLG & 0x08));   
    CLKSEL = 0x80;      // select PLL as clock

    // wait for clock transition to finish
    for (ix = 0; ix < 60; ix++);
 
 DDRM |= 0xFC;    // port M - all outputs, full drive by default  //CONNECTED TO LEDS
 DDRS &= 0xF2;    // configure transmitter pin as output and receiver pin as inputs
  
  //INITIALIZE SCI
 
    SCI0BDH = 0x00;
 // Set up SCI (rs232): SCI BR reg= BusFreq(=24MHz)/16/baudrate
    SCI0BDL = (unsigned char)(1500000/115200);  //emb edited
    ltmp = (150000000/115200) - ((long)SCI0BDL*100);
    if(ltmp > 50) {
        SCI0BDL++;   // round up
    }
    SCI0CR1 =  0x00;
    //SCI0CR2 = 0x24;   // TIE=0,RIE = 1; TE=0,RE =1  FROM ORIGINAL CODE
 //SCI0CR2 = 0x2c;     /* Transmit enable, read enable */ //WITH NO INTERRUPTS  0x24 is not working because transmit is disabled (may be)
 SCI0CR2 = 0xfc; ////0x24;
 
 asm cli;  //enable interrupts
 
 SCI0DRL = 0x31;  //TRANSMIT 1
 
 while(!(SCI0SR1 & 0x40)){ }
 
//RECEIVE

    while(!(SCI0SR1 & 0x20)){  }    //wait for reception
 i = SCI0DRL;

//transmit

 SCI0DRL = i;  //TRANSMIT 1
 
 while(!(SCI0SR1 & 0x40)){ } //wait to transmit
 
   //off 4,5,6 leds on ms2 board
     PTM |= 0x10;
     PTM|= 0x08; // PTM |= 0x08;
        PTM |= 0x20;
 

while(1)
 {
    //off 4,5,6 leds on ms2 board
    PTM &= ~0x10;  //bit4 LED5
   
    PTM &= ~0x08;  //bit3 LED4
   
    PTM &= ~0x20;  //bit5 LED6
   
   
    for(i = 0;i<=50000;i++) { }
   
    for(i = 0;i<=50000;i++) { }
      
    for(i = 0;i<=50000;i++) { }
   
    for(i = 0;i<=50000;i++) { }
   
  //ON 4,5,6 leds on ms2 board
    PTM |= 0x10;
   
    PTM |= 0x08;
   
    PTM |= 0x20;
   
    for(i = 0;i<=50000;i++) { }
   
    for(i = 0;i<=50000;i++) { }
      
    for(i = 0;i<=50000;i++) { }
   
    for(i = 0;i<=50000;i++) { }

 }
}

#pragma CODE_SEG DEFAULT

 

 

Thanks,

Embitel

Labels (1)
0 Kudos
Reply
11 Replies

909 Views
embitel
Contributor I

Hello everyone,

 

Same post i have edited little

 

im using MC9S12C64..


Using Codewarrior 5.1 with PE USB MULTILINK.

 

My code is as follows

 

The problem PC is jumping to ISR and after completing ISR, control is looping back to again ISR.

 

control is not retruning from interrupt.

 

I have seen stack frame in sigle step everything seems stacking.

 

Can someone please look the code and tell where is the problem in code.

 

Memory model is "banked".

 

#include <hidef.h>      /* common defines and macros */
//#include "derivative.h"      /* derivative-specific definitions */
#include "hcs12def.h"      /* common defines and macros */

 

 

//------------------------------------------------​--------------------------------------------------​-----------------------------------------------
#pragma CODE_SEG NON_BANKED
//------------------------------------------------​--------------------------------------------------​-----------------------------------------------
interrupt 20 void  SCI1_Isr (void)
{
 volatile unsigned char scicr2,scisr1;
 static unsigned char RxCnt=0;
 unsigned int i;
 scisr1 = SCI0SR1;
 scicr2 = SCI0CR2;
 
  i = SCI0DRL;

//transmit

 SCI0DRL = i;  //TRANSMIT 1
 
     PTM |= 0x10; //glowing led
    
    PTM |= 0x08; //glowing led
    
    PTM |= 0x20; //glowing led
}
//------------------------------------------------​--------------------------------------------------​----------------------------------------------
#pragma CODE_SEG DEFAULT
//------------------------------------------------​--------------------------------------------------​----------------------------------------------

 

#pragma CODE_SEG NON_BANKED
void main(void) {
  /* put your own code here */
  int ix;
  long ltmp;  

  unsigned int i;
  
    // initalize PLL - reset default is Oscillator clock
    // 8 MHz oscillator, PLL freq = 48 MHz, 24 MHz bus,
    //  divide by 16 for timer of 2/3 usec tic
    PLLCTL &= 0xBF;     // Turn off PLL so can change freq
    SYNR = 0x02;        // set PLL/ Bus freq to 48/ 24 MHz
    REFDV = 0x00;
    PLLCTL |= 0x40;     // Turn on PLL
    // wait for PLL lock
    while (!(CRGFLG & 0x08));   
    CLKSEL = 0x80;      // select PLL as clock

    // wait for clock transition to finish
    for (ix = 0; ix < 60; ix++);
 
 DDRM |= 0xFC;    // port M - all outputs, full drive by default  //CONNECTED TO LEDS
 DDRS &= 0xF2;    // configure transmitter pin as output and receiver pin as inputs
  
  //INITIALIZE SCI
 
    SCI0BDH = 0x00;
 // Set up SCI (rs232): SCI BR reg= BusFreq(=24MHz)/16/baudrate
    SCI0BDL = (unsigned char)(1500000/115200);  //emb edited
    ltmp = (150000000/115200) - ((long)SCI0BDL*100);
    if(ltmp > 50) {
        SCI0BDL++;   // round up
    }
    SCI0CR1 =  0x00;
    //SCI0CR2 = 0x24;   // TIE=0,RIE = 1; TE=0,RE =1  FROM ORIGINAL CODE
 //SCI0CR2 = 0x2c;     /* Transmit enable, read enable */ //WITH NO INTERRUPTS  0x24 is not working because transmit is disabled (may be)
 SCI0CR2 = 0xfc; ////0x24;
 
 asm cli;  //enable interrupts
 
 SCI0DRL = 0x31;  //TRANSMIT 1
 
 while(!(SCI0SR1 & 0x40)){ }
 
//RECEIVE

    while(!(SCI0SR1 & 0x20)){  }    //wait for reception
 i = SCI0DRL;

//transmit

 SCI0DRL = i;  //TRANSMIT 1
 
 while(!(SCI0SR1 & 0x40)){ } //wait to transmit
 
   //off 4,5,6 leds on ms2 board
     PTM |= 0x10;
     PTM|= 0x08; // PTM |= 0x08;
        PTM |= 0x20;
 

while(1)
 {
    //off 4,5,6 leds on ms2 board
    PTM &= ~0x10;  //bit4 LED5
   
    PTM &= ~0x08;  //bit3 LED4
   
    PTM &= ~0x20;  //bit5 LED6
   
   
    for(i = 0;i<=50000;i++) { }
   
    for(i = 0;i<=50000;i++) { }
      
    for(i = 0;i<=50000;i++) { }
   
    for(i = 0;i<=50000;i++) { }
   
  //ON 4,5,6 leds on ms2 board
    PTM |= 0x10;
   
    PTM |= 0x08;
   
    PTM |= 0x20;
   
    for(i = 0;i<=50000;i++) { }
   
    for(i = 0;i<=50000;i++) { }
      
    for(i = 0;i<=50000;i++) { }
   
    for(i = 0;i<=50000;i++) { }

 }
}

#pragma CODE_SEG DEFAULT

 

 

Thanks,

Embitel

0 Kudos
Reply

909 Views
kef
Specialist I

To clear SCI receiver flags you need to perform these steps 1) read SCI status register, 2) read data register. To clear SCI transmitter flags you need to 1) read SCI status register, 2) write data register:

 

 scisr1 = SCI0SR1;  //  read status 

 i = SCI0DRL;          //  read data, receiver flags are cleared

 

/transmit

scisr1 = SCI0SR1;                   // read status

SCI0DRL = i;  //                     clear transmitter flags

0 Kudos
Reply

909 Views
embitel
Contributor I

Hi Kef,

 

i have edited isr as follows but still interrupt is not retunting to main

 

interrupt 20 void  SCI1_Isr (void)
{
 volatile unsigned char scicr2,scisr1;
 static unsigned char RxCnt=0;
 unsigned int i;
 scisr1 = SCI0SR1;
 scicr2 = SCI0CR2;
 
 
 scisr1 = SCI0SR1;  //  read status

 i = SCI0DRL;          //  read data, receiver flags are cleared

 

//transmit

scisr1 = SCI0SR1;                   // read status

SCI0DRL = i;  //                     clear transmitter flags

 
     PTM |= 0x10;
   
    PTM |= 0x08;
   
    PTM |= 0x20;

}

 

 


kef wrote:

 

To clear SCI receiver flags you need to perform these steps 1) read SCI status register, 2) read data register. To clear SCI transmitter flags you need to 1) read SCI status register, 2) write data register:

 

 scisr1 = SCI0SR1;  //  read status 

 i = SCI0DRL;          //  read data, receiver flags are cleared

 

/transmit

scisr1 = SCI0SR1;                   // read status

SCI0DRL = i;  //                     clear transmitter flags


 

0 Kudos
Reply

909 Views
kef
Specialist I

You mean that your ISR is sending something again and again and this looks like not return from ISR? It is normal, because you don't disable TCIE and TIE interrupts in your ISR. You need to disable them when you have nothing to send.

0 Kudos
Reply

909 Views
embitel
Contributor I

 

Hi kef,

 

i added the statement

 

asm cli;  //WHICH DISABLES ALL INTERRUPTS

 

as sooon as i enter ISR.

 

BUT STILL THE PROBLEM PERSISTS.

0 Kudos
Reply

909 Views
kef
Specialist I

cli enables masked interrupts. Even if you use sei in interrupt, which won't do anything, since I bit is already set when you enter interrupt, return from interrupt will reenable interrupts, unless you manipulate copy of old status register value, which was saved on the stack when ISR was called.

0 Kudos
Reply

909 Views
embitel
Contributor I

Hi kef,

 

Thanks for ur valuable reply.

 

the final working code is as follows.

 

The mistake was LOADING REGISTER SCI0CR2 = 0xEC; at initialization

 

one question regarding ur previous reply " disable TCIE and TIE interrupts in your ISR" 

 

in the present code it is not done as u mentioned but still its working fine.

 

any logic in this ......

 

 

#include <hidef.h>      /* common defines and macros */
//#include "derivative.h"      /* derivative-specific definitions */
#include "hcs12def.h"      /* common defines and macros */


 unsigned int received = 0x31,i;
unsigned char received_flag = 0;

//-------------------------------------------------------------------------------------------------------------------------------------------------
#pragma CODE_SEG NON_BANKED
//-------------------------------------------------------------------------------------------------------------------------------------------------
interrupt 20 void  SCI1_Isr (void)
{
 volatile unsigned char scicr2,scisr1;

  // scisr1 = SCI0SR1;
  //scicr2 = SCI0CR2;
 
   
 //if ((scisr1 & 0x20 ) && (scisr1 & 0x28) )  //receive    if RDRF set
 if (SCI0SR1 & 0x20 ) //receive interrupt
 {
   
 received_flag = 0;
 
 //SCI0CR2 &= 0xdf;    //disable receive interrupt flag
   
   // scisr1 = SCI0SR1;   //clear register data
    received = SCI0DRL;
  
    //SCI0DRL = i;
 
 }
 
 
// if(SCI0SR1 & 0x80 )   //transmit      if TDRE set
// {
   // scisr1 = SCI0SR1; //clear register data
   
    //SCI0CR2 &= 0x3f;    //disable transmit interrupt flag
 //}
  
 }


//------------------------------------------------------------------------------------------------------------------------------------------------
#pragma CODE_SEG DEFAULT
//------------------------------------------------------------------------------------------------------------------------------------------------

 

#pragma CODE_SEG NON_BANKED
void main(void) {
  /* put your own code here */
  int ix;
  long ltmp;  

 
 
 
 
    // initalize PLL - reset default is Oscillator clock


    // 8 MHz oscillator, PLL freq = 48 MHz, 24 MHz bus,


    //  divide by 16 for timer of 2/3 usec tic
    PLLCTL &= 0xBF;     // Turn off PLL so can change freq
    SYNR = 0x02;        // set PLL/ Bus freq to 48/ 24 MHz
    REFDV = 0x00;
    PLLCTL |= 0x40;     // Turn on PLL
    // wait for PLL lock
    while (!(CRGFLG & 0x08));   
    CLKSEL = 0x80;      // select PLL as clock

    // wait for clock transition to finish
    for (ix = 0; ix < 60; ix++);
 
 DDRM |= 0xFC;    // port M - all outputs, full drive by default  //CONNECTED TO LEDS
 DDRS &= 0xF2;    // configure transmitter pin as output and receiver pin as inputs
 
 
  //INITIALIZE SCI
 
    SCI0BDH = 0x00;
 // Set up SCI (rs232): SCI BR reg= BusFreq(=24MHz)/16/baudrate
    SCI0BDL = (unsigned char)(1500000/115200);  //emb edited
    ltmp = (150000000/115200) - ((long)SCI0BDL*100);
    if(ltmp > 50) {
        SCI0BDL++;   // round up
    }
    SCI0CR1 =  0x00;
    //SCI0CR2 = 0x24;   // TIE=0,RIE = 1; TE=0,RE =1  FROM ORIGINAL CODE
 //SCI0CR2 = 0x2c;     /* Transmit enable, read enable */ //WITH NO INTERRUPTS  0x24 is not working because transmit 

 

 //SCI0CR2 = 0xEC; ////0x24;  // THIS IS WHERE THE MISTAKE IS  I THINK
 SCI0CR2 = 0x2c;
 
 asm cli;  //enable interrupts
 
 
   //off 4,5,6 leds on ms2 board
     PTM |= 0x10;
     PTM|= 0x08; // PTM |= 0x08;
        PTM |= 0x20;
 

while(1)
 {
    //off 4,5,6 leds on ms2 board
    PTM &= ~0x10;  //bit4 LED5
   
    PTM &= ~0x08;  //bit3 LED4
   
    PTM &= ~0x20;  //bit5 LED6
   
   
    if (received_flag == 0)
    {
   received_flag = 1;
   while(!(SCI0SR1 & 0x40));  //transmission complete flag
   SCI0DRL = received;  //initially TRANSMIT 1 and next transmit whatever received
  } 
    
        
    for(i = 0;i<=50000;i++) { }
    
  //ON 4,5,6 leds on ms2 board
    PTM |= 0x10;
   
    PTM |= 0x08;
   
    PTM |= 0x20;
   
    for(i = 0;i<=50000;i++) { }
    
 }
}

#pragma CODE_SEG DEFAULT

 

0 Kudos
Reply

909 Views
kef
Specialist I

Logic? Yes, now you have TCIE and TIE disabled  in the main(), SCI0CR2 = 0x2c;.

0 Kudos
Reply

909 Views
embitel
Contributor I

kef wrote:

Logic? Yes, now you have TCIE and TIE disabled  in the main(), SCI0CR2 = 0x2c;.



is it not required to clear these bits in  ISR???

0 Kudos
Reply

909 Views
kef
Specialist I

Of course no.

0 Kudos
Reply

909 Views
embitel
Contributor I

Ok

 

thanks for all your repies

0 Kudos
Reply