How to configure multiple Interrupts in S12XE Family

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

How to configure multiple Interrupts in S12XE Family

1,502 Views
haricharanreddy
Contributor II

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

pastedImage_1.png

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 

Tags (2)
0 Kudos
8 Replies

1,094 Views
lama
NXP TechSupport
NXP TechSupport

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

 

0 Kudos

1,093 Views
kef2
Senior Contributor IV

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 

0 Kudos

1,094 Views
haricharanreddy
Contributor II

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

0 Kudos

1,094 Views
kef2
Senior Contributor IV

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

0 Kudos

1,094 Views
haricharanreddy
Contributor II

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

0 Kudos

1,094 Views
kef2
Senior Contributor IV
  • 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 ?

Nothing happens, PIT priority doesn't change after configuring CAN priority.

Edward

0 Kudos

1,094 Views
haricharanreddy
Contributor II

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


0 Kudos

1,094 Views
kef2
Senior Contributor IV

Yes, if you look at 

Interrupt Request Configuration Data Registers (INT_CFDATA0–7)

, reset default value for PRIOLVL[2:0] is 001.

Edward

0 Kudos