Interrupt Priority in MC9S12XS128

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

Interrupt Priority in MC9S12XS128

Jump to solution
1,475 Views
sirishmadhusudh
Contributor I

Hi,

     Can somebody describe the procedure to set the interrupt priority for timer channel 0 interrupt?

i am using this interrupt for refreshing a LED matrix, and the period is 80 micro sec. since i also have CAN interrupt enabled, i'm able to see some deviation in the periodicity, which is causing flicker in the LED's. The LED's appear to flash randomly.

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

Sirish,

Interrupt priority can be easily changed using this macro from CodeWarrior project wizard generated files:

#define ROUTE_INTERRUPT(vec_adr, cfdata)                \

  INT_CFADDR= (vec_adr) & 0xF0;                         \

  INT_CFDATA_ARR[((vec_adr) & 0x0F) >> 1]= (cfdata)

Usage is ...  Unfortunately you didn't say what variant of S12X are you using. In case it is ECT channel 0 on S12XE:

ROUTE_INTERRUPT ( Vectch0,  desired_priority_level) ;

Vectch0 is vector address defined in derivative header file.

ROUTE_INTERRUPT() is a half of the task. To make interrupts nested, you need to reenable interrupts in all lower priority interrupt handlers.

Priority levels mechanism works this way: when CPU enters interrupt  handler for level (for example) 2 interrupt, it sets I bit and sets current priority level to 2. I=1 disables all interrupts, PRIO=2 disables all interrupts with priority levels <=2. To enable Interrupts with priority levels >=3, you need to clear I bit. You should clear I bit (asm CLI;) as soon as you enter lower priority interrupts.

View solution in original post

0 Kudos
5 Replies
847 Views
kef
Specialist I

Sirish,

Interrupt priority can be easily changed using this macro from CodeWarrior project wizard generated files:

#define ROUTE_INTERRUPT(vec_adr, cfdata)                \

  INT_CFADDR= (vec_adr) & 0xF0;                         \

  INT_CFDATA_ARR[((vec_adr) & 0x0F) >> 1]= (cfdata)

Usage is ...  Unfortunately you didn't say what variant of S12X are you using. In case it is ECT channel 0 on S12XE:

ROUTE_INTERRUPT ( Vectch0,  desired_priority_level) ;

Vectch0 is vector address defined in derivative header file.

ROUTE_INTERRUPT() is a half of the task. To make interrupts nested, you need to reenable interrupts in all lower priority interrupt handlers.

Priority levels mechanism works this way: when CPU enters interrupt  handler for level (for example) 2 interrupt, it sets I bit and sets current priority level to 2. I=1 disables all interrupts, PRIO=2 disables all interrupts with priority levels <=2. To enable Interrupts with priority levels >=3, you need to clear I bit. You should clear I bit (asm CLI;) as soon as you enter lower priority interrupts.

0 Kudos
846 Views
RadekS
NXP Employee
NXP Employee

Just small specification: If there are more pending interrupts, interrupt with highest priority wins.

If there are more pending interrupts with the same priority and this priority is the highest, Interrupt with higher vector address wins (For example ECT0 will be executed prior ECT1).

Interrupt nesting and priority setting is already nicely described by kef.

I would like note here also typical software error which could cause described behavior:

If we use more than one timer channel, we should take care on flag clearing mechanism.

In short: TFLG1_C0F=1; is wrong command for flag clearing. This command cause reading TFLG1 register, modify C0F bit and write whole byte into TFLG1 register. This way we clear all pending flags.

Correct way should be for example: TFLG1=0x01; //clear C0F flag

Note: this is general recommendation, timer is just typical case.

More details you can find in our application note AN2554 Clearing and Disabling Interrupt Flags

http://www.freescale.com/files/microcontrollers/doc/app_note/AN2554.pdf


846 Views
sirishmadhusudh
Contributor I

Radek,

     Thanks for the support. In my design, i am using multiple timer channels for interrupt. I have set the Timer Fast Flag Clear All (TSCR1_TFFCA) bit. I am using timer channel 0 and 1 independently.

The Timer Prescaler Selected gives me a clock of 16 micro sec.

For timer zero ISR, for a period of 80usec, i do TC0 = TCNT + 5 each time i enter the ISR.

for timer 1 ISR, for a period of 1 msec, i update the TC1 as TC1 = TC1+63.

In both ISRs i do not clear the TFLG1_C0F and TFLG1_C1F flags since i have set the TSCR1_TFFCA bit. Am i doing it right?

Regards,

Sirish

0 Kudos
846 Views
RadekS
NXP Employee
NXP Employee

Yes, when you enabled TFFCA bit, read from an input capture or a write to the output compare channel will clear appropriate flags. So, you don't need take care about flag clearing.

0 Kudos
846 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

on S12X the priority scheme is different. Totally software interrupt priority is 0-7. the default software priority of all interrupts is 1. 0 means the interurpt is disabled. the higher number, the higher priority. For a interrupt, we can change its interrupt priority from 1 to 2 to higher its priority. the order of vector number is nothing to do with priority. I ever made a sample code on this topic. Hope you can lean something here!