Hi all,
I am using MC9S12XE family microcontroller I want to configure Multiple Interrupts in my device like Timer,SPI,CAN, etc.. while I am going through chapter 6 of Datasheet I came across this
What I understand from the above context is
I can configure only 8 Vector Interrupt Requests out of 128 vector interrupt request selected by the INT_CFADDR
for Example
if I am given
/*Ignore programming Syntax*/
IVBR= 0xFF;
INT_CFADDR=0xA0;
then starting from 0xA000 -0xA007 only these Vector Interrupts I can Configure in INT_CFDATA0-7
What about the other Interrupts If I need to configure?
If you look into the interrupt vector Table of micro controller present in DataSheet SPI0 interrupt vector location(0XFFD8) AND CAN0 Transmit Interrupt location is (0XFFB0)
CAN0 Receive Interrupt location is (0XFFB2)
so I can't configure CAN0 interrupts along with SPI0 interrupts at a time
Same thing with other Interrupts also ..
This is what I understood after reading the those Interrupt configuration Registers in chapter 6 of Datasheet
Now my question is
1.So How Can I Overcome this problem by using this micro controller family?
2.So How can I configure the other interrupts like CANTx,CAN Rx,SPI along with Timer Interrupt ?
If My understanding is wrong Please Excuse me, and please tell me the correct way of configuring the Multiple Vector Interrupt requests
Datasheet:https://www.nxp.com/docs/en/data-sheet/MC9S12XEP100RMV1.pdf
Thanks In Advance:smileyhappy:
HariCharan
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:
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
Hi HariCharan,
You don't need to touch INT_CFADDR and INT_CFDATAx at all, unless you want to enable interrupt nesting. If nesting is required (bad idea usually), then still you are not limited to 8 levels. To save precious address space 8 INT_CFDATAx registers are paged. Changing INT_CFADDR you map to INT_CFDATAx different 8 interrupts priority registers. From CodeWarrior project wizard created project with XGATE enabled:
#define ROUTE_INTERRUPT(vec_adr, cfdata) \
INT_CFADDR= (vec_adr) & 0xF0; \
INT_CFDATA_ARR[((vec_adr) & 0x0F) >> 1]= (cfdata)
....
ROUTE_INTERRUPT(SOFTWARETRIGGER0_VEC, 0x81); /* RQST=1 and PRIO=1 */
You can use ROUTE_INTERRUPT macro to set up interrupt priority of selected interrupt. As you may see, first INT_CFADDR is modified, which maps different 8 vectors to INT_CFDATA , then specific INT_CFDATA is modified with specified cfdata priority settings.
Edward
Hi Edward
I am not using Xgate for interrupt processing currently I just want my interrupts need to be processed by CPU only
currently I want to configure CAN Interrupts and PTI Interrupts Can you explain How it should be done?
Thanks in advance
Hi,
Looks like you read word Xgate and decided to ignore my reply.
ROUTE_INTERRUPT(SOFTWARETRIGGER0_VEC, 0x81); /* RQST=1 and PRIO=1 */
^^ this is used both to redirect specific interrupt to XGATE (2nd argument has bit 7 set), and to set interrupt priority. So to let SOFTWARETRIGGER0 be handled by CPU and set interrupt priority to 3 you call this macro with RQST=0 and PRIO=3:
ROUTE_INTERRUPT(SOFTWARETRIGGER0_VEC, 3);
Edward
Thanks for early reply
What should I do when I have multiple source of interrupts
for example
I have PTI and CAN Interrupts which are located in different vector locations of a vector Table
If I use
ROUTE_INTERRUPT()
function for PTI
and
ROUTE_INTERRUPT()
function for CAN in same code
After Configuring of CAN interrupt vector location and priority using ROUTE_INTERRUPT()
what happens to PTI interrupt and priority configurations in CFADDR and CFDATA registers which were configured earlier ?
If you provide an example it will be helpful
Thanks in advance
Nothing happens, PIT priority doesn't change after configuring CAN priority.
Edward
Thanks Edward
Is there any Default Priority to all 128 interrupts that micro controller follow i.e,
if don't configure any priority at all using priority configuration registers(IVBR,CFADDR,CFDATA) what Micro controller does if any interrupt occurs ?
Thanks in advance
Yes, if you look at
Interrupt Request Configuration Data Registers (INT_CFDATA0–7)
, reset default value for PRIOLVL[2:0] is 001.
Edward