S32 SDK
interrupt_manager.h
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 #if !defined(INTERRUPT_MANAGER_H)
19 #define INTERRUPT_MANAGER_H
20 
21 #include "device_registers.h"
22 
23 
51 /*******************************************************************************
52  * Definitions
53  ******************************************************************************/
54 
55 #if FEATURE_MSCM_HAS_CPU_INTERRUPT_ROUTER
56 
58 typedef enum
59 {
60  INTERRUPT_MANAGER_TARGET_SELF = -2,
61  INTERRUPT_MANAGER_TARGET_OTHERS = -1,
62  INTERRUPT_MANAGER_TARGET_NONE = 0,
63  INTERRUPT_MANAGER_TARGET_CP0 = 1,
64  INTERRUPT_MANAGER_TARGET_CP1 = 2,
65  INTERRUPT_MANAGER_TARGET_CP0_CP1 = 3
66 } interrupt_manager_cpu_targets_t;
67 
68 #endif /* FEATURE_MSCM_HAS_CPU_INTERRUPT_ROUTER */
69 
71 typedef void (* isr_t)(void);
72 
73 /*******************************************************************************
74  * Default interrupt handler - implemented in startup.s
75  ******************************************************************************/
77 void DefaultISR(void);
78 
79 /*******************************************************************************
80  * API
81  ******************************************************************************/
82 
83 #if defined(__cplusplus)
84 extern "C" {
85 #endif /* __cplusplus*/
86 
89 
108 void INT_SYS_InstallHandler(IRQn_Type irqNumber,
109  const isr_t newHandler,
110  isr_t* const oldHandler);
111 
124 void INT_SYS_EnableIRQ(IRQn_Type irqNumber);
125 
135 void INT_SYS_DisableIRQ(IRQn_Type irqNumber);
136 
143 void INT_SYS_EnableIRQGlobal(void);
144 
151 void INT_SYS_DisableIRQGlobal(void);
152 
163 static inline void INT_SYS_SetPriority(IRQn_Type irqNumber, uint8_t priority)
164 {
165  /* Check IRQ number and priority. */
167  DEV_ASSERT(priority < (uint8_t)(1U << FEATURE_NVIC_PRIO_BITS));
168 
169  uint8_t shift = (uint8_t) (8U - FEATURE_NVIC_PRIO_BITS);
170 
171  if ((int32_t)irqNumber < 0)
172  {
173  uint32_t intVectorId = ((uint32_t)(irqNumber) & 0xFU);
174  uint32_t regId = intVectorId / 4U;
175  /* Compute pointer to SHPR register - avoid MISRA violation. */
176  volatile uint8_t * shpr_reg_ptr = ((regId == 1U) ? (volatile uint8_t *)&S32_SCB->SHPR1 : ((regId == 2U) ? (volatile uint8_t *)&S32_SCB->SHPR2 : (volatile uint8_t *)&S32_SCB->SHPR3));
177  /* Set Priority for Cortex-M System Interrupts */
178  shpr_reg_ptr[intVectorId % 4U] = (uint8_t)(((((uint32_t)priority) << shift)) & 0xffUL);
179  }
180  else
181  {
182  /* Set Priority for device specific Interrupts */
183  S32_NVIC->IP[(uint32_t)(irqNumber)] = (uint8_t)(((((uint32_t)priority) << shift)) & 0xFFUL);
184  }
185 }
186 
197 static inline uint8_t INT_SYS_GetPriority(IRQn_Type irqNumber)
198 {
199  /* Check IRQ number. */
201 
202  uint8_t priority = 0U;
203  uint8_t shift = (uint8_t) (8U - FEATURE_NVIC_PRIO_BITS);
204 
205  if ((int32_t)irqNumber < 0)
206  {
207  uint32_t intVectorId = ((uint32_t)(irqNumber) & 0xFU);
208  uint32_t regId = intVectorId / 4U;
209 
210  /* Compute pointer to SHPR register - avoid MISRA violation. */
211  volatile const uint8_t * shpr_reg_ptr = ((regId == 1U) ? (volatile uint8_t *)&S32_SCB->SHPR1 : ((regId == 2U) ? (volatile uint8_t *)&S32_SCB->SHPR2 : (volatile uint8_t *)&S32_SCB->SHPR3));
212  /* Get Priority from Cortex-M System Interrupts */
213  priority = (uint8_t)(shpr_reg_ptr[intVectorId % 4U] >> (shift));
214  }
215  else
216  {
217  /* Get Priority for device specific Interrupts */
218  priority = (uint8_t)(S32_NVIC->IP[(uint32_t)(irqNumber)] >> shift);
219  }
220 
221  return priority;
222 }
223 
233 static inline void INT_SYS_ClearPending(IRQn_Type irqNumber)
234 {
235  /* Check IRQ number */
236  DEV_ASSERT(0 <= (int32_t)irqNumber);
238 
239 #if FEATURE_MSCM_HAS_CPU_INTERRUPT_ROUTER
240 
241  if ((FEATURE_DIRECTED_CPU_INT_MIN <= irqNumber) && (irqNumber <= FEATURE_DIRECTED_CPU_INT_MAX))
242  {
243  /* Clear Directed CPU Pending Interrupt */
244  switch (MSCM->CPXNUM)
245  {
246  case 0:
247  MSCM->IRCP0IR |= (1UL << ((uint32_t)irqNumber - (uint32_t)FEATURE_DIRECTED_CPU_INT_MIN));
248  break;
249  default:
250  MSCM->IRCP1IR |= (1UL << ((uint32_t)irqNumber - (uint32_t)FEATURE_DIRECTED_CPU_INT_MIN));
251  break;
252  }
253  return;
254  }
255 #endif /* FEATURE_MSCM_HAS_CPU_INTERRUPT_ROUTER */
256 
257  /* Clear Pending Interrupt */
258  S32_NVIC->ICPR[(uint32_t)(irqNumber) >> 5U] = (uint32_t)(1UL << ((uint32_t)(irqNumber) & (uint32_t)0x1FU));
259 }
260 
269 static inline void INT_SYS_SetPending(IRQn_Type irqNumber)
270 {
271  /* Check IRQ number */
272  DEV_ASSERT(0 <= (int32_t)irqNumber);
274 
275  /* Set Pending Interrupt */
276  S32_NVIC->ISPR[(uint32_t)(irqNumber) >> 5U] = (uint32_t)(1UL << ((uint32_t)(irqNumber) & (uint32_t)0x1FU));
277 }
278 
289 static inline uint32_t INT_SYS_GetPending(IRQn_Type irqNumber)
290 {
291  /* Check IRQ number */
292  DEV_ASSERT(0 <= (int32_t)irqNumber);
294 
295 #if FEATURE_MSCM_HAS_CPU_INTERRUPT_ROUTER
296  /* Get Directed CPU Pending Interrupt */
297  if ((FEATURE_DIRECTED_CPU_INT_MIN <= irqNumber) && (irqNumber <= FEATURE_DIRECTED_CPU_INT_MAX))
298  {
299  return (((((MSCM->CPXNUM != 0UL) ? MSCM->IRCP1IR : MSCM->IRCP0IR) &
300  (1UL << ((uint32_t)irqNumber - (uint32_t)FEATURE_DIRECTED_CPU_INT_MIN))) != 0UL) ? 1UL : 0UL);
301  }
302 #endif /* FEATURE_MSCM_HAS_CPU_INTERRUPT_ROUTER */
303 
304  /* Get Pending Interrupt */
305  return ((uint32_t)(((S32_NVIC->ISPR[(((uint32_t)irqNumber) >> 5UL)] & (1UL << (((uint32_t)irqNumber) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
306 }
307 
317 static inline uint32_t INT_SYS_GetActive(IRQn_Type irqNumber)
318 {
319  /* Check IRQ number */
320  DEV_ASSERT(0 <= (int32_t)irqNumber);
322 
323  /* Get Active Interrupt */
324  return ((uint32_t)(((S32_NVIC->IABR[(((uint32_t)irqNumber) >> 5UL)] & (1UL << (((uint32_t)irqNumber) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
325 }
326 
327 #if FEATURE_MSCM_HAS_CPU_INTERRUPT_ROUTER
328 
338 static inline void INT_SYS_GenerateDirectedCpuInterrupt(IRQn_Type irqNumber, interrupt_manager_cpu_targets_t cpu_target)
339 {
340  /* Check IRQ number */
341  DEV_ASSERT(FEATURE_DIRECTED_CPU_INT_MIN <= irqNumber);
342  DEV_ASSERT(irqNumber <= FEATURE_DIRECTED_CPU_INT_MAX);
343 
344  uint32_t reg_val = MSCM_IRCPGIR_INTID((uint32_t)irqNumber - (uint32_t)FEATURE_DIRECTED_CPU_INT_MIN);
345 
346  switch (cpu_target)
347  {
348  case INTERRUPT_MANAGER_TARGET_SELF:
349  reg_val |= MSCM_IRCPGIR_TLF(2);
350  break;
351  case INTERRUPT_MANAGER_TARGET_OTHERS:
352  reg_val |= MSCM_IRCPGIR_TLF(1);
353  break;
354  case INTERRUPT_MANAGER_TARGET_NONE:
355  case INTERRUPT_MANAGER_TARGET_CP0:
356  case INTERRUPT_MANAGER_TARGET_CP1:
357  case INTERRUPT_MANAGER_TARGET_CP0_CP1:
358  reg_val |= (MSCM_IRCPGIR_TLF(0) | MSCM_IRCPGIR_CPUTL(cpu_target));
359  break;
360  default:
361  /* Not treated case ? */
362  break;
363  }
364 
365  /* Generate Directed CPU Interrupt */
366  MSCM->IRCPGIR = reg_val;
367 }
368 
369 #endif /* FEATURE_MSCM_HAS_CPU_INTERRUPT_ROUTER */
370 
373 #if defined(__cplusplus)
374 }
375 #endif /* __cplusplus*/
376 
379 #endif /* INTERRUPT_MANAGER_H */
380 /*******************************************************************************
381  * EOF
382  ******************************************************************************/
static uint32_t INT_SYS_GetActive(IRQn_Type irqNumber)
Get Active Interrupt.
static void INT_SYS_ClearPending(IRQn_Type irqNumber)
Clear Pending Interrupt.
#define S32_NVIC
Definition: S32K144.h:9191
static void INT_SYS_SetPending(IRQn_Type irqNumber)
Set Pending Interrupt.
void DefaultISR(void)
Default ISR.
IRQn_Type
Defines the Interrupt Numbers definitions.
Definition: S32K144.h:269
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
static uint8_t INT_SYS_GetPriority(IRQn_Type irqNumber)
Get Interrupt Priority.
#define FEATURE_INTERRUPT_IRQ_MAX
static void INT_SYS_SetPriority(IRQn_Type irqNumber, uint8_t priority)
Set Interrupt Priority.
#define S32_SCB
Definition: S32K144.h:9795
void INT_SYS_EnableIRQGlobal(void)
Enables system interrupt.
static uint32_t INT_SYS_GetPending(IRQn_Type irqNumber)
Get Pending Interrupt.
#define MSCM
Definition: S32K144.h:7864
#define FEATURE_NVIC_PRIO_BITS
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
void(* isr_t)(void)
Interrupt handler type.
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.