INTERRUPT PROBLEM: INTERRUPTS STOPS TO WORK!!!!

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

INTERRUPT PROBLEM: INTERRUPTS STOPS TO WORK!!!!

3,387 Views
osanz
Contributor I
Hi to everyone;
 
I'm working on the driver developing of MCF52233, and using a M52233DEMO board, and Codewarrior 5.7. Up to now everithing has worked more or less fine, but while working on DTIM0 driver, a strange problem has appeared.:
 
-A after some seconds, the interrupt system of the MCU stops so any interrupt is working no more, if DTIM0 interrupt is enabled.
 
The MCU is still working because i can stop the program and run by step.
 
I have no idea why the interrupts stops to work suddenly. Does anyone has this problem???
 
Thanks a lot.
Labels (1)
0 Kudos
9 Replies

979 Views
Petter_fupp
Contributor I
A few thoughts:
- The interrupt priority mask field in the status register can be set to a high value (7?)
- The ICR registers or vector table might be incorrect

More details would be great.

Cheers,
Petter
0 Kudos

979 Views
osanz
Contributor I
Hi peter;
 
thanks a lot for your reply.
 
The priorities for all interrupts are defined as follows:
 
MCF_INTC0_ICR04 = 0x3F; 
MCF_INTC0_ICR13 = 0x3F;
MCF_INTC0_ICR14 = 0x3F;
MCF_INTC0_ICR15 = 0x3F; 
MCF_INTC0_ICR19 = 0x3F; 
MCF_INTC0_ICR55 = 0x3F;
 
These are all interrupts i'm using on this project. But note that i have tried to change these parameters by decreasing the INTERUPT LEVEL and similar problem happens.
 
Basically i'm doing the following; timer init:
 
void ColdfireDTIMERInit( BYTE timerNum, BYTE prescalerValue, DWORD timeoutValue, BYTE interruptEnable )
{
 
 WORD tempVar = 0;
 
 
 
 if( timerNum == 0)
 {
 
 MCF_GPIO_PTCPAR  = 0x01;      //COMO GPIO
// MCF_GPIO_DDRTC  = 0x0F;      //SALIDA                           
// MCF_GPIO_PORTTC  = 0x00; 
 
 MCF_DTIM0_DTXMR = 0;                    
 
 MCF_DTIM0_DTER  = 0x02;                    
 
 MCF_DTIM0_DTRR  = timeoutValue;                    
 
 tempVar = prescalerValue;
 tempVar = tempVar << 8;
 tempVar |= 0x0033;
 
 if( interruptEnable )
 {
 tempVar |= 0x0010; 
 }
 
 MCF_DTIM0_DTMR = tempVar;
 
 //MCF_DTIM0_DTCR                      
 //MCF_DTIM0_DTCN
  
 }

 }
 
And the timer ISR:
 
__declspec (interrupt) void DTIM0_isr()
{
 
 MCF_DTIM0_DTER = 0x02;
 MCF_DTIM0_DTCN = 0;
 GTaskSwitcher |= 0x08; //DTIM_0
 
}
 
GTaskSwitcher is a global variable i'm using as a task switch flag on the main while loop ( the same is applied on the other interrupt routines:
 
main()
{
 
......
// Some inits etc...
......
 
while(1){
 
 if( GTaskSwitcher & 0x08 )  
 {
ColdfireDissableAllInterrupts();
 printf("\n\rDTIM_0_IRQ->%d", tempCnt);    // To see what is happening....
 fflush(stdout);
 GTaskSwitcher = GTaskSwitcher & 0xF7;
 tempCnt++;
ColdfireEnableAllInterrupts();
 }
 
....
....
}
}
 
 
OK, with this code, the printf runs up to tempCnt =10496. Then no any interrupt will work anymore. Before all the other interrupts are working fine. If I dissable the DTIM0 interrupt the problem disappear also.
 
What do you think?
 
 
 
0 Kudos

979 Views
osanz
Contributor I
Hello again;
 
I have canged to this:
 
MCF_INTC0_ICR04 = 0x3F; 
MCF_INTC0_ICR13 = 0x3E;
MCF_INTC0_ICR14 = 0x3D;
MCF_INTC0_ICR15 = 0x3C; 
MCF_INTC0_ICR19 = 0x3B; 
MCF_INTC0_ICR55 = 0x3A;
 
But same result, after some cicles, the interrupts stops to work.
 
....
0 Kudos

979 Views
osanz
Contributor I
Hello again;
 
After many changes i have found that there is an incompatibility between PIT0 timer and DTIM0 timer.
 
If i disable PIT0 interrupt the system seems to work fine, i have tried to put different interrupt priorities for each timer source but the result is the same. After many cicles ALL iterrupts stos if both timers are working at same time.
 
?
0 Kudos

979 Views
mjbcswitzerland
Specialist V
Osanz

In this case I suggest you analyse the effect of the two interrupts ocurring at the same time.

For example the flag you are setting:
GTaskSwitcher |= 0x08; //DTIM_0

This reads the variable to a register and then sets the bit before writing it back.
If a different interrupt also accesses this variable (between the read and write) it can cause bits to be lost.

Try protecting this flag by disabling all interrupts before doing it, and reenabling afterwards.

Alternatively don't use bits in a single variable but a seperate variable for each interrupt routine - then the IRQs can not effect each other.

Regards

Mark

www.uTasker.com

0 Kudos

979 Views
osanz
Contributor I
Hi Mark;
 
Thanks a lot for your reply.
 
I'm going to test it, but i'm affraid that the problem is not here.
 
I have found that the problem is the interrupt concurrence, because if i disable all interrupts inside the each interrupt routine, it seems to work.
 
Today i'm going to add AD converter to the party, lets see if reaaly it works like this....
0 Kudos

979 Views
mjbcswitzerland
Specialist V
Osanz

If you try using bit fields, also protect
GTaskSwitcher = GTaskSwitcher & 0xXX;
by doing

disable_interrupts();   // protect flag when clearing bits
GTaskSwitcher = GTaskSwitcher & 0xF7;
enable_interrupts();   // leave critical region

The reason is the same.

If you disable all interrupts inside the interrupt routines you are protecting them for each other - there will be no nested interrupts - and also you protect the setting of flags from other interrupt routines. Therefore I think that you have already done more or less that which I suggested.


Regards

Mark



0 Kudos

979 Views
osanz
Contributor I
Mark;
 
Thanks again for your support. As i commneted i'm triyng to setup the ADC converters also.
This time my problem is the ADC conversion complete is not working.....?
 
Here is the ADC init code:
 
void ColdfireADCInit( WORD clockDivisor, BYTE interruptEnable )
{
                    
//GPIO config.
MCF_GPIO_PANPAR  = 0xFF;      //COMO ADC                    
MCF_ADC_ADLST1 = 0x3210;                    
MCF_ADC_ADLST2 = 0x7654;                                          
MCF_ADC_ADSDIS = 0x0000;                     
//MCF_ADC_ADZCC
//MCF_ADC_ADSTAT                      
//MCF_ADC_ADLSTAT                     
//MCF_ADC_ADZCSTAT                    
 
MCF_ADC_POWER = 0x00D4;                     
MCF_ADC_CAL = 0x0000;                      
 if( interruptEnable )
 {
 MCF_ADC_CTRL1 = 0x2802;     
 }
 else
 {
 MCF_ADC_CTRL1 = 0x2002;
 }
MCF_ADC_CTRL2 = ( clockDivisor & 0x001F ); 
}
 
Al the other configurations has been tested via INTFRCH0 register, so interrupts are enabled and service routiones are working but, ADC by itself do not generate these ones.
 
As a guide i need ( to have the first contact with this ADC ):
-Loop Sequential.
-Internal voltage reference.
-Only scan complete interrupt for both converters.
-Power mg. totally manual.
-I think thats all.
 
 
Any idea?
 
0 Kudos

979 Views
Petter_fupp
Contributor I
Almost forgot: make sure all ICR register values are unique (none of the ones in use should be equal another).
0 Kudos