1 /* -------------------------------- Arctic Core ------------------------------
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
6 * This source code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * -------------------------------- Arctic Core ------------------------------*/
20 #include "irq_types.h"
23 extern TaskType Os_Arc_CreateIsr( void (*entry)(void ), uint8_t prio, const char *name );
24 extern void *Irq_VectorTable[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];
27 static inline void Irq_Setup() {
28 vimREG->FIRQPR0 = 0x0;
29 vimREG->FIRQPR1 = 0x0;
32 void Irq_Init( void ) {
40 * @param stack_p Ptr to the current stack.
42 * The stack holds C, NVGPR, VGPR and the EXC frame.
45 #define MAX_WAIT_COUNT 1000
46 void *Irq_Entry( void *stack_p )
50 // This is the current hardware interrupt channel that we are processing.
51 volatile sint8 channel;
53 // This is the current OS-interrupt vector that we are processing.
54 volatile sint8 virtualChannel;
56 // Get the highest pending interrupt.
57 volatile uint32 c = 0;
59 channel = IrqGetCurrentInterruptSource();
61 } while (channel < 0 && c < MAX_WAIT_COUNT);
63 if (c >= MAX_WAIT_COUNT) {
64 // No interrupt is pending
68 // In most cases the OS-channel is the same as the hardware channel.
69 virtualChannel = channel;
71 // Special case for software interrupts.
73 // Get the emulated interrupt channel.
74 virtualChannel = systemREG1->SSISR1;
77 /*stack = (uint32_t *)stack_p;
78 struct OsTaskVar * pcb = (struct OsTaskVar *)Irq_VectorTable[virtualChannel];
79 // Save the hardware channel in the PCB, so that Os_Isr knows which interrupt channel to deactivate.
80 pcb->vector = channel;
82 // Don't know what to pass here yet. Use the virtual channel for now, but
83 // probably need to pass channel as well.
84 stack = Os_Isr(stack, virtualChannel);
91 * Attach an ISR type 1 to the interrupt controller.
98 void Irq_AttachIsr1( void (*entry)(void), void *int_ctrl, uint32_t vector, uint8_t prio) {
100 // TODO: Use NVIC_InitVector(vector, osPrioToCpuPio(pcb->prio)); here
104 * NVIC prio have priority 0-15, 0-highest priority.
105 * Autosar does it the other way around, 0-Lowest priority
116 static inline int osPrioToCpuPio( uint8_t prio ) {
123 * Attach a ISR type 2 to the interrupt controller.
130 void Irq_AttachIsr2(TaskType tid,void *int_ctrl,IrqType vector ) {
133 pcb = Os_TaskGet(tid);
134 Irq_VectorTable[vector] = (void *)pcb;
135 IrqActivateChannel(vector);
137 // TOdo replace NVIC_InitVector(vector, osPrioToCpuPio(pcb->prio));
140 void Irq_EnableVector( int16_t vector, int priority, int core ) {
142 if (vector < NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS) {
143 IrqActivateChannel(vector);
145 /* Invalid vector! */
151 * Generates a soft interrupt, ie sets pending bit.
152 * This could also be implemented using ISPR regs.
156 void Irq_GenerateSoftInt( IrqType vector ) {
157 IrqActivateChannel(SSI);
158 systemREG1->SSISR1 = (0x75 << 8) | vector;
162 * Get the current priority from the interrupt controller.
166 uint8_t Irq_GetCurrentPriority( Cpu_t cpu) {
170 // SCB_ICSR contains the active vector