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
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
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
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 statusi = 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
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.
Hi kef,
i added the statement
asm cli; //WHICH DISABLES ALL INTERRUPTS
as sooon as i enter ISR.
BUT STILL THE PROBLEM PERSISTS.
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.
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
Logic? Yes, now you have TCIE and TIE disabled in the main(), SCI0CR2 = 0x2c;.
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???
Of course no.
Ok
thanks for all your repies