Proper reset of port interrupts on MKL25Z128VLK4

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Proper reset of port interrupts on MKL25Z128VLK4

ソリューションへジャンプ
812件の閲覧回数
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

ラベル(2)
タグ(2)
0 件の賞賛
1 解決策
575件の閲覧回数
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 件の賞賛
3 返答(返信)
576件の閲覧回数
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 件の賞賛
575件の閲覧回数
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 件の賞賛
575件の閲覧回数
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 件の賞賛