Hi,
Can you remember my answer for a case 00174354 (I also placed it bellow) where I wrote about XGATE. Now, I will talk about CPU only….
CPU can process as many interrupt as possible with priority level set from 0 to 7 (0 disables interrupt). Interrupt nesting is possible if I bit is cleared and interrupt with higher priority is asking for service.
- HW interrupt have priority above I-bit maskable interrupt.
Each I bit maskable interrupt has following possibilities of enale/disable:
- Clear/set I-bit – global enable/disable for all I-bit maskable interrupts at once
- Set CFADDR and CFDATA to select interrupt priority (0 – disable interrupt even it is enabled in registers settings for given peripher)
- There is interrupt enable bit in the registers setting for each peripheral.
If I do not want to use XGATE and only do not want to change priority of interrupts then it is enough to enable the interrupt by iven bit in peripheral setting registers.
However if I want to set a priority of the CPU interrupt only I can do that by macro:
#define SET_PRIORITY(channel, priority) \
INT_CFADDR= (channel \
INT_CFDATA_ARR[channel & 0x07] = priority
// from data sheet vector table, for example, for PIT module
#define PIT0 0x7A // vector address
#define PIT1 0x78 // vector address
#define PIT2 0x76 // vector address
#define PIT3 0x74 // vector address
#define SOFTWARETRIGGER0_VEC 0x72
#define SOFTWARETRIGGER1_VEC 0x70
#define ATD0_AUTO_COMPARE 0x3E
Then anytime anywhere:
SET_PRIORITY(ATD0_AUTO_COMPARE,1); // ATD0 auto compare, routed to CPU, priority 1
SET_PRIORITY(SOFTWARETRIGGER0_VEC, 3);
SET_PRIORITY(PIT0, 1); // Route to CPU, priority 1
SET_PRIORITY(SOFTWARETRIGGER1_VEC, 7); // Route to CPU, priority 7
…
Somewhere in time later, I want to change priority:
SET_PRIORITY(PIT0, XGATE, 5); // Route to CPU, priority 5
Only to highlight, I have already wrote in the answer for a case 00174354 following.
In the history I have used more variants of the definition, especially in the case when the device does not contain XGATE and there is CPU only. For example….
Simplified:
#define SET_PRIORITY(channel, priority) \
INT_CFADDR= (channel \
INT_CFDATA_ARR[channel & 0x07] = priority
Or
#define ROUTE_INTERRUPT(vec_adr, cfdata) \
INT_CFADDR= (vec_adr) & 0xF0; \
INT_CFDATA_ARR[((vec_adr) & 0x0F) >> 1]= (cfdata)
When you have to be sure what you are writing for priority:
ROUTE_INTERRUPT(ATD0_VEC, 0x82); // Route to XGATE. Priority 2
ROUTE_INTERRUPT(PIT0, 0x03); // Route to CPU, priority 3
I have also attached a few examples...what I have described above
Some more things from my PC can be found
https://community.nxp.com/docs/DOC-329209
**********************************************************
Answer on the case 00174354 when you asked question about XGATE interrupts:
I am talking about XGATE only for priority explanation….
Can can process as many interrupt as possible with priority level set fro 0 to 7 (0 disables interrupt). But….
- In the case of interrupt nesting there is only possibility that interrupt of level 1,2,3 can be interrupted only by interrupt with level 4,5,6,7. Also, interrupts in the same block are not able to be nested. For example, when priority level 6 is processed priority level 6 is not able to interrupt it.
- HW interrupt have priority above I-bit maskable interrupt and they are also not routable to XGATE.
The principle to set priority, I use is:
#define CPU 0x00
#define XGATE 0x80
#define ROUTE_INTERRUPT_SET_PRIORITY(channel, cpu_xgate, priority) \
INT_CFADDR= (channel \
INT_CFDATA_ARR[channel & 0x07] = (cpu_xgate|priority)
// from data sheet vector table, for example, for PIT module
#define PIT0 0x7A // vector address
#define PIT1 0x78 // vector address
#define PIT2 0x76 // vector address
#define PIT3 0x74 // vector address
#define SOFTWARETRIGGER0_VEC 0x72
#define SOFTWARETRIGGER1_VEC 0x70
#define ATD0_AUTO_COMPARE 0x3E
Then anytime anywhere:
ROUTE_INTERRUPT_SET_PRIORITY(ATD0_AUTO_COMPARE,CPU,1); // ATD0 auto compare, routed to CPU, priority 1
OUTE_INTERRUPT_SET_PRIORITY(SOFTWARETRIGGER0_VEC, CPU, 3);
ROUTE_INTERRUPT_SET_PRIORITY(PIT0, XGATE, 1); // Route to XGATE, priority 1
ROUTE_INTERRUPT(SOFTWARETRIGGER1_VEC, XGATE, 7); // Route to XGATE priority 7
…
…
…
…
…
Somewhere in time later, I want to change priority:
ROUTE_INTERRUPT_SET_PRIORITY(PIT0, XGATE, 5); // Route to XGATE, priority 5
Of course, you should keep and/or process correctly routing. If the has isr written for XGATE is not correct to route it to XGATE.
In the history I have used more variants of the definition, especially in the case when the device does not contain XGATE and there is CPU only. For example….
Simplified:
#define SET_PRIORITY(channel, priority) \
INT_CFADDR= (channel \
INT_CFDATA_ARR[channel & 0x07] = priority
Or
#define ROUTE_INTERRUPT(vec_adr, cfdata) \
INT_CFADDR= (vec_adr) & 0xF0; \
INT_CFDATA_ARR[((vec_adr) & 0x0F) >> 1]= (cfdata)
When you have to be sure what you are writing for priority:
ROUTE_INTERRUPT(ATD0_VEC, 0x82); // Route to XGATE. Priority 2
ROUTE_INTERRUPT(PIT0, 0x03); // Route to CPU, priority 3
I have also attached a few examples...what I have described above
Some more things from my PC can be found
https://community.nxp.com/docs/DOC-329209