HCS12NE64 misses some edge interrupt

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

HCS12NE64 misses some edge interrupt

4,132 Views
tyson
Contributor I
In HCS12NE64,
I configure Port G Pins as rising edge interrupt.
Pulses are given to all port pins at different frequencies.
 
PortG interrupt routine()
{
  1) Storing the PortG interrupt flag register temporarily
   
   if(G4 Set)
  {
     /* Clear Port G4 interrupt Flag */
    
    /* Toggle One Port Pin (any Port H Pins)
  }
  
  if(G5 Set)
  {
     /* Clear Port G5 interrupt Flag */
    
    /* Toggle One Port Pin (any Port H Pins)
  }
 
  if(G6 Set)
  {
     /* Clear Port G6 interrupt Flag */
    
    /* Toggle One Port Pin (any Port H Pins)
  }
  
  if(G7 Set)
  {
     /* Clear Port G7 interrupt Flag */
    
    /* Toggle One Port Pin (any Port H Pins)
  }
}
 
Some Strange things are happening
1) Processor is missing edges randomly at different times.
2) How it is possible?
Labels (1)
0 Kudos
3 Replies

481 Views
EMontanez
NXP Employee
NXP Employee
Hi tyson,
 
Can you send your actual source code instead of pseudo code for this Port G edge interrupt service routine?
 
I think your most likely using a read-modify-write instruction like BSET when clearing the respective flag in the Port G flag register. If you do this, you can accidently clear flags for other Port G pins that are pending interrupt. Therefore, you will not see all the interrupts you expected.
 
For some flag clearning rules, please read application note AN2554.
 
Just a snippet of my cheat sheet for flag clearing:
 

For Assembly Language:

 

The bits in the CRGFLG register are "write 1 to clear". To clear specific bits you must use the instruction sequence:

 

Method 1:

LDAA bitmask

STAA CRGFLG

(Of course B could be used)

 

Or

 

Method 2:

BCLR CRGFLG, ~bitmask

Could be used.

 

You cannot use:

Wrong Method:

BSET CRGFLG, bitmask

On this register, because BSET is a "read-modify-write" instruction: all set bits will be cleared.

 

**************************************************************************************

 

For C Language:

 

Assuming CRGFLG is defined as

volatile unsigned char CRGFLG @ (0x37 + REG_BASE);

Then,

 

Method 1 – Flag Register:

CRGFLG = 0x80;  /* clear RTIF */

Will translate to LDAA/B STAA/B and clear RTIF and nothing else.

To make this easier, define bitmasks for the register:

 #define RTIF 0x80

#define PORF 0x40

Etc.

Then write,

CRGFLG = RTIF; /* clear RTIF */

Or

CRGFLG = RTIF + PORF; /* clear RTIF and PORF */

 

Method 2 – Flag Register:

To get the BCLR CRGFLG, $7F instruction, you need to use

CRGFLG &= 0x80; /* clear RTIF */

Or

CRGFLG &= RTIF; /* clear RTIF */

0 Kudos

481 Views
rocco
Senior Contributor II
EMontanez wrote:

Method 2:


BCLR CRGFLG, ~bitmask


Could be used.



You cannot use:


Wrong Method:


BSET CRGFLG, bitmask


On this register, because BSET is a "read-modify-write" instruction: all set bits will be cleared.




This may be a stupid question, but isn't BCLR a read-modify-write instruction as well?

Sorry if I'm confused (I do that a lot).

I also can't get this darn HTML to work right . . .
0 Kudos

481 Views
EMontanez
NXP Employee
NXP Employee
rocco,
 
You are absolutely right, BCLR is also a read-modify-instruction. I need to update my cheat sheet to be more specific to BSET as a dangerous read-modify-instruction for clearing flags. Since users need to write a 1 to clear a flag, the BSET instruction is most likely used. However, its nature of using an "AND" function to mask the register can unexpectedly erase other flag bits. On the other hand, if using a BCLR instruction with the inverse mask, which uses an "OR" function, it will work ok.
 
Best bet is to use the LDAA STAA method.

Message Edited by EMontanez on 02-20-2006 04:13 PM

0 Kudos