Proper reset of port interrupts on MKL25Z128VLK4

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

Proper reset of port interrupts on MKL25Z128VLK4

Jump to solution
804 Views
stefandz
Contributor II

Hi everyone

I'm trying to learn best practise with port interrupts for the M0+ chip I'm working with - the MKL25Z128VLK4 on the FRDM-KL15Z board. I'm using an external falling edge interrupt on PORTD Pin 4. It's all set up nicely using Processor Expert in CodeWarrior and I can correctly trigger into my PORTD ISR and test PORTD_PCR4 to determine the cause of the interrupt. So far so good. Since my ISR needs to trigger comms (which I can't do inside the ISR) I just test, clear and assert an asynchronous flag which I deal with elsewhere in the main loop. All works with this piece of code:

if(PORTD_PCR4 & 1<<24){

     PORTD_PCR4 |= 1<<24; // 1 clears, not 0...

     touchFlag = TRUE;

}


Easy, right? Except that it's not exactly ideal. It's using a non-atomic read-modify-write in the |= (along with the inline shift). This means that theoretically, another bit in the register could change between the read and the write. In this case it is unlikely (as each PCR only includes its own ISF) but I just wanted to see if there was a better way out there.


All thoughts gratefully received.


Stefan

0 Kudos
1 Solution
567 Views
chris_brown
NXP Employee
NXP Employee

Hi Stefan,

Theoretically, another bit could change, but since the chip really doesn't change the other bits in these registers dynamically (except in certain cases where the user doesn't have access to that particular functionality), they won't change unless you write them.  So I don't think your concern is really anything to worry about.

You need the read, modify write unless you want to change all of the settings of the pin control register back to the default (which it doesn't sound like you do).  Using PORTD_PCR4 = 1 << 24 will definitely change all of the other bits in the register (if they were something other than 0).  The one thing I would suggest is that you use the masks in the Freescale header files.  So if I were doing this, my code would be

if(PORTD_PCR4 & PORT_PCR_ISF_MASK){

     PORTD_PCR4 |= PORT_PCR_ISF_MASK; // 1 clears, not 0...

     touchFlag = TRUE;

}


This will eliminate the shift and reduce the number of instructions.  It will also make your code more readable and intuitive. 


Hope this helps,

Chris

View solution in original post

0 Kudos
3 Replies
568 Views
chris_brown
NXP Employee
NXP Employee

Hi Stefan,

Theoretically, another bit could change, but since the chip really doesn't change the other bits in these registers dynamically (except in certain cases where the user doesn't have access to that particular functionality), they won't change unless you write them.  So I don't think your concern is really anything to worry about.

You need the read, modify write unless you want to change all of the settings of the pin control register back to the default (which it doesn't sound like you do).  Using PORTD_PCR4 = 1 << 24 will definitely change all of the other bits in the register (if they were something other than 0).  The one thing I would suggest is that you use the masks in the Freescale header files.  So if I were doing this, my code would be

if(PORTD_PCR4 & PORT_PCR_ISF_MASK){

     PORTD_PCR4 |= PORT_PCR_ISF_MASK; // 1 clears, not 0...

     touchFlag = TRUE;

}


This will eliminate the shift and reduce the number of instructions.  It will also make your code more readable and intuitive. 


Hope this helps,

Chris

0 Kudos
567 Views
stefandz
Contributor II

Thanks Chris

I thought that I was probably worrying about nothing, but good to see the correct usage of the masks.

Thanks for your help!

Stefan

0 Kudos
567 Views
JimDon
Senior Contributor III

I am not sure that your concerns a re well founded, but in any even since 1 clears and 0 does nothing you can say:

PORTD_PCR4 = 1<<24;

The compiler will pre-compute 1<<24 so this should just be a constant.


0 Kudos