S32 SDK
interrupt_manager.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
7  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
10  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
12  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
14  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
15  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
16  * THE POSSIBILITY OF SUCH DAMAGE.
17  */
18 
53 #include "interrupt_manager.h"
54 
55 /*******************************************************************************
56  * Definitions
57  ******************************************************************************/
58 
62 static int32_t g_interruptDisableCount = 0;
63 
69 extern uint32_t __VECTOR_RAM[((uint32_t)(FEATURE_INTERRUPT_IRQ_MAX)) + 16U + 1U];
70 
71 /*******************************************************************************
72  * Code
73  ******************************************************************************/
74 
75 /*FUNCTION**********************************************************************
76  *
77  * Function Name : INT_SYS_InstallHandler
78  * Description : Install an interrupt handler routine for a given IRQ number
79  * This function will let application register/replace the interrupt
80  * handler for specified IRQ number. IRQ number is different than Vector
81  * number. IRQ 0 will start from Vector 16 address. Refer to reference
82  * manual for details. Also refer to startup_<CPU>.s file for each chip
83  * family to find out the default interrupt handler for each device. This
84  * function will convert the IRQ number to vector number by adding 16 to
85  * it.
86  *
87  * Note : This method is applicable only if interrupt vector is
88  * copied in RAM, __flash_vector_table__ symbol is used to
89  * control this from linker options.
90  * Implements INT_SYS_InstallHandler_Activity
91  *
92  *END**************************************************************************/
94  const isr_t newHandler,
95  isr_t* const oldHandler)
96 {
97  /* Check IRQ number */
100  DEV_ASSERT(__VECTOR_RAM != 0U);
101  /* Check whether there is vector table in RAM */
102  DEV_ASSERT((uint32_t)__VECTOR_RAM == S32_SCB->VTOR);
103 
104  /* Save the former handler pointer */
105  if (oldHandler != (isr_t *) 0)
106  {
107  *oldHandler = (isr_t)__VECTOR_RAM[((int32_t)irqNumber) + 16];
108  }
109 
110 #if FEATURE_MSCM_HAS_INTERRUPT_ROUTER
111 
112  DEV_ASSERT((uint32_t)irqNumber < MSCM_IRSPRC_COUNT);
113  /* Check routing is not read-only in case it needs to be written */
114  uint16_t cpu_enable = (uint16_t)(1UL << (MSCM->CPXNUM));
115  if ((MSCM->IRSPRC[irqNumber] & cpu_enable) == 0U)
116  {
117  DEV_ASSERT((MSCM->IRSPRC[irqNumber] & (uint16_t)(MSCM_IRSPRC_RO_MASK)) == (uint16_t)MSCM_IRSPRC_RO(0));
118  }
119 
120 #endif /* FEATURE_MSCM_HAS_INTERRUPT_ROUTER */
121 
122  /* Set handler into vector table */
123  __VECTOR_RAM[((int32_t)irqNumber) + 16] = (uint32_t)newHandler;
124 }
125 
126 /*FUNCTION**********************************************************************
127  *
128  * Function Name : INT_SYS_EnableIRQ
129  * Description : Enables an interrupt for a given IRQ number.
130  * It calls the system NVIC API to access the interrupt control
131  * register and MSCM (if available) API for interrupt routing.
132  * The input IRQ number does not include the core interrupt, only
133  * the peripheral interrupt, from 0 to a maximum supported IRQ.
134  * Implements INT_SYS_EnableIRQ_Activity
135  *END**************************************************************************/
137 {
138  /* Check IRQ number */
139  DEV_ASSERT(0 <= (int32_t)irqNumber);
141 
142  /* Enable interrupt */
143  S32_NVIC->ISER[(uint32_t)(irqNumber) >> 5U] = (uint32_t)(1UL << ((uint32_t)(irqNumber) & (uint32_t)0x1FU));
144 
145 #if FEATURE_MSCM_HAS_INTERRUPT_ROUTER
146 
147  /* Enable routing to current CPU */
148  uint16_t cpu_enable = (uint16_t)(1UL << (MSCM->CPXNUM));
149  MSCM->IRSPRC[irqNumber] |= cpu_enable;
150 
151 #endif /* FEATURE_MSCM_HAS_INTERRUPT_ROUTER */
152 }
153 
154 /*FUNCTION**********************************************************************
155  *
156  * Function Name : INT_SYS_DisableIRQ
157  * Description : Disable individual interrupt for a specified IRQ
158  * It calls the system NVIC API to access the interrupt control register
159  * and MSCM (if available) API for interrupt routing.
160  * Implements INT_SYS_DisableIRQ_Activity
161  *
162  *END**************************************************************************/
164 {
165  /* Check IRQ number */
166  DEV_ASSERT(0 <= (int32_t)irqNumber);
168 
169  /* Disable interrupt */
170  S32_NVIC->ICER[((uint32_t)(irqNumber) >> 5U)] = (uint32_t)(1UL << ((uint32_t)(irqNumber) & (uint32_t)0x1FU));
171 
172 #if FEATURE_MSCM_HAS_INTERRUPT_ROUTER
173 
174  /* Disable routing to current CPU */
175  uint16_t cpu_enable = (uint16_t)(1UL << (MSCM->CPXNUM));
176  MSCM->IRSPRC[irqNumber] &= (uint16_t)~(cpu_enable);
177 
178 #endif /* FEATURE_MSCM_HAS_INTERRUPT_ROUTER */
179 
180 }
181 
182 /*FUNCTION**********************************************************************
183  *
184  * Function Name : INT_SYS_EnableIRQGlobal
185  * Description : Enable system interrupt
186  * This function will enable the global interrupt by calling the core API
187  * Implements INT_SYS_EnableIRQGlobal_Activity
188  *
189  *END**************************************************************************/
191 {
192  /* Check and update */
193  if (g_interruptDisableCount > 0)
194  {
196 
197  if (g_interruptDisableCount <= 0)
198  {
199  /* Enable the global interrupt*/
201  }
202  }
203 }
204 
205 /*FUNCTION**********************************************************************
206  *
207  * Function Name : INT_SYS_DisableIRQGlobal
208  * Description : Disable system interrupt
209  * This function will disable the global interrupt by calling the core API
210  * Implements INT_SYS_DisableIRQGlobal_Activity
211  *
212  *END**************************************************************************/
214 {
215  /* Disable the global interrupt */
217 
218  /* Update counter*/
220 }
221 
222 /*******************************************************************************
223  * EOF
224  ******************************************************************************/
uint32_t __VECTOR_RAM[((uint32_t)(FEATURE_INTERRUPT_IRQ_MAX))+16U+1U]
Declaration of vector table. FEATURE_INTERRUPT_IRQ_MAX is the highest interrupt request number...
#define S32_NVIC
Definition: S32K144.h:9191
IRQn_Type
Defines the Interrupt Numbers definitions.
Definition: S32K144.h:269
#define FEATURE_INTERRUPT_IRQ_MIN
void INT_SYS_DisableIRQ(IRQn_Type irqNumber)
Disables an interrupt for a given IRQ number.
void INT_SYS_DisableIRQGlobal(void)
Disable system interrupt.
#define DEV_ASSERT(x)
Definition: devassert.h:78
#define FEATURE_INTERRUPT_IRQ_MAX
static int32_t g_interruptDisableCount
Counter to manage the nested callings of global disable/enable interrupt.
#define S32_SCB
Definition: S32K144.h:9795
#define ENABLE_INTERRUPTS()
Enable FPU.
Definition: s32_core_cm4.h:84
void INT_SYS_EnableIRQGlobal(void)
Enables system interrupt.
#define MSCM
Definition: S32K144.h:7864
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
void(* isr_t)(void)
Interrupt handler type.
#define DISABLE_INTERRUPTS()
Disable interrupts.
Definition: s32_core_cm4.h:93
void INT_SYS_InstallHandler(IRQn_Type irqNumber, const isr_t newHandler, isr_t *const oldHandler)
Installs an interrupt handler routine for a given IRQ number.