[MC9S12C64] Interrupt Priority for Input Capture

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

[MC9S12C64] Interrupt Priority for Input Capture

Jump to solution
779 Views
Pogo
Contributor III

Hi All,

 

I've two IOC pin IOC0 and IOC3 and use them to capture input signal's pulse width. The frequency of IOC0's signal is greater than IOC3's. But sometimes the IOC3 pin will lost to capture some signals. If I want to guarantee that the signal to IOC3 pin will not lost to capture signal. How can I do?

Changing the priority of interrupt for IOC3 as highest. (HPRIO = 0xE8) ? Or you have another solution, please tell me. Thanks a lot.

 

Reagrds,

Pogo

Labels (1)
0 Kudos
1 Solution
455 Views
kef
Specialist I

So I was right suspecting that you are clearing timer flags incorrectly.

 

    TFLG1 |= 0x01; //Clear flag
 ^^ here you are clearing all TFLG1 flags, including channel 0 and 3 flags

 

    TFLG1 |= 0x08; //Clear flag
Same  ^^ here. You are clearing all TFLG1 flags, including channel 0 and 3 flags

 

Search forum for flag clearing like stuf and you will find it desribed many times. Reading TFLG1, ORing read bit pattern with  mask of flag  you are interested in, then writing resulting bitpattern back to TFLG1, you are writing "1" not just to flag you are interested in, but you write more "1"-es and clearing not just flag you are interested in. Correct code to clear channel 3 flag is either

 

   TFLG1 = (1<<3);

 

or

 

  TFLG1 &= (1<<3); // please note that there's no ~ operator in front of bitpattern on the right

 

View solution in original post

0 Kudos
6 Replies
455 Views
kef
Specialist I

How does clear flag code looks like? C? Asm?

Input capture misses events only when input pulse is too narrow (<2 bus clocks as stated in datasheets).

Another problem maybe that new capture event overwrites old TCx, so you need to service IC on time (ECT timer has some extra capture features like buffered capture etc).

HPRIO won't help a lot. It is effective only when two or more interrupts ar pending at the same time. It matters when you expect two or more interrupts happening at exactly the same time, and you wish to service one of them first.

0 Kudos
455 Views
Pogo
Contributor III
interrupt void ISR_Timer0(void){    ...  //local variable define    TFLG1 |= 0x01; //Clear flag    ...  // do some calculation}interrupt void ISR_Timer3(void){    ...  //local variable define    TFLG1 |= 0x08; //Clear flag    ...  //do some calculation}

 Now, the ISR_Timer3 will lost some signal interrupt.  If I clear flag after doing some calculation, can I solve this problem?

Thanks for your reply!!

 

Pogo

0 Kudos
456 Views
kef
Specialist I

So I was right suspecting that you are clearing timer flags incorrectly.

 

    TFLG1 |= 0x01; //Clear flag
 ^^ here you are clearing all TFLG1 flags, including channel 0 and 3 flags

 

    TFLG1 |= 0x08; //Clear flag
Same  ^^ here. You are clearing all TFLG1 flags, including channel 0 and 3 flags

 

Search forum for flag clearing like stuf and you will find it desribed many times. Reading TFLG1, ORing read bit pattern with  mask of flag  you are interested in, then writing resulting bitpattern back to TFLG1, you are writing "1" not just to flag you are interested in, but you write more "1"-es and clearing not just flag you are interested in. Correct code to clear channel 3 flag is either

 

   TFLG1 = (1<<3);

 

or

 

  TFLG1 &= (1<<3); // please note that there's no ~ operator in front of bitpattern on the right

 

0 Kudos
455 Views
Lundin
Senior Contributor IV

Always, I repeat, always disassemble ISRs where you clear interrupt source flags. Incorrectly cleared interrupt flags is possibly the greatest cause of bugs in embedded systems, no matter what MCU flavour you are using. You have to read the disassembly and see what actually goes on, and whether this is compatible with the hardware registers or not.

 

For this particular case, Kef is likely assuming that you are using the Codewarrior, where the code TFLG |= 0x01 is indeed incorrect. CW will translate that to a read-modify-write access, and since TFLG is cleared by writing 1 to a flag, all flags will be cleared and not just the one you were interested in. But on another compiler, the same code could give the correct output, using a single bit set instruction instead.

0 Kudos
455 Views
kef
Specialist I

Lundin, pelase stop spreading rumors about read modify write instructions. You are wrong! First of all I didn't say that TFLG1 |= 0x1 is correct. Second, IT DOESN'T MATTER WHAT COMPILER you will use, and if that compiler will use BSET or LDAA/ORAA/STAA like sequence, in all imagineable cases it won't work properly and will clear all flags that are set in this flags register! The same applies to bitfields provided by Freescale compilers. TFLG1_C0F = 1 will clear all TFLG1 flags. TFLG1_C0F = 0 will clear all TFLG1 flags except C0F.

INDEED READ MODIFY WRITE instructions are ABSULUTELY OK, provided you are using them properly. What's wrong with these codes to clear bit 3 in TFLG1? These work perfectly well:

 

    TFLG1 &= (1<<3); // please note that there's no ~ on the righ like would be used to clear bits in regular variables.

 

and

 

   BCLR  TFLG1, #~(1<<3)   or equivalent   BCLR TFLG1, #0xF7

0 Kudos
455 Views
Pogo
Contributor III

Hi kef,

 

Thanks for your reply.

I've serach all "clear flag" keyword in this forum.

If I want to clear Timer0 and Timer3, I need to write the belowing code to clear them.

TFLG1  = 0x01; //Clear Timer 0 flag

 

TFLG1 = 0x08; //Clear Timer 3 flag.

 

 

Pogo

 

0 Kudos