1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\r
6 * This source code is free software; you can redistribute it and/or modify it
\r
7 * under the terms of the GNU General Public License version 2 as published by the
\r
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
\r
10 * This program is distributed in the hope that it will be useful, but
\r
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
\r
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
\r
14 * -------------------------------- Arctic Core ------------------------------*/
\r
16 #include "internal.h"
\r
18 #include "irq_types.h"
\r
21 extern void * Irq_VectorTable[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];
\r
22 extern uint8 Irq_IsrTypeTable[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];
\r
24 extern void _start (void);
\r
27 void Irq_Init( void ) {
\r
31 void Irq_EOI( void ) {
\r
35 // IRQ debug information
\r
36 // Stores irq nr on erroneous interrupt
\r
37 volatile sint16 bad_irq_nr = -1;
\r
39 // Stores context info on erroneous interrupt
\r
40 volatile uint8 bad_irq_context_bank = 0;
\r
41 volatile void* bad_irq_context_address = 0;
\r
43 void bad_irq(uint8_t irq_nr, void **stack) {
\r
45 // Save number of caught interrupt
\r
46 bad_irq_nr = irq_nr;
\r
48 // Fetch address and page of where we were interrupted, from context
\r
49 uint16 bank_and_ccr = (uint16)(*(stack + 4));
\r
50 bad_irq_context_bank = (bank_and_ccr & 0xFF00) >> 8;
\r
51 bad_irq_context_address = *(stack + 8);
\r
56 void *Irq_Entry( uint8_t irq_nr, void *stack )
\r
58 void* vector = (void *)Irq_VectorTable[irq_nr];
\r
60 // trap uninitialized interrupts
\r
61 if (vector == NULL) {
\r
62 bad_irq(irq_nr, stack);
\r
65 if( Irq_GetIsrType(irq_nr) == ISR_TYPE_1 ) {
\r
66 // It's a function, just call it.
\r
72 // Let the kernel handle the rest,
\r
73 return Os_Isr(stack, vector);
\r
78 * Attach an ISR type 1 to the interrupt controller.
\r
85 void Irq_AttachIsr1( void (*entry)(void), void *int_ctrl, uint32_t vector, uint8_t prio) {
\r
86 Irq_VectorTable[vector] = (void *)entry;
\r
87 Irq_SetIsrType(vector, ISR_TYPE_1);
\r
92 * Attach a ISR type 2 to the interrupt controller.
\r
98 void Irq_AttachIsr2(TaskType tid,void *int_ctrl,IrqType vector ) {
\r
101 pcb = os_find_task(tid);
\r
102 Irq_VectorTable[vector] = (void *)pcb;
\r
103 Irq_IsrTypeTable[vector] = PROC_ISR2;
\r
109 * Generates a soft interrupt, ie sets pending bit.
\r
110 * This could also be implemented using ISPR regs.
\r
114 void Irq_GenerateSoftInt( IrqType vector ) {
\r
119 * Get the current priority from the interrupt controller.
\r
123 uint8_t Irq_GetCurrentPriority( Cpu_t cpu) {
\r
127 // SCB_ICSR contains the active vector
\r
132 // ##################### INTERRUPT TRANSLATE TABLE #######################
\r
133 #define IRQ_MAP(x) irq_##x
\r
135 const struct interrupt_vectors __attribute__((section(".vectors"))) vectors =
\r
137 pwm_shutdown_handler:
\r
138 IRQ_MAP(pwm_shutdown),
\r
148 IRQ_MAP(can4_wake),
\r
156 IRQ_MAP(can3_wake),
\r
164 IRQ_MAP(can2_wake),
\r
172 IRQ_MAP(can1_wake),
\r
180 IRQ_MAP(can0_wake),
\r
193 selfclk_mode_handler:
\r
194 IRQ_MAP(selfclk_mode),
\r
197 accb_overflow_handler:
\r
198 IRQ_MAP(accb_overflow),
\r
199 mccnt_underflow_handler:
\r
200 IRQ_MAP(mccnt_underflow),
\r
216 // Timer and Accumulator
\r
217 acca_input_handler:
\r
218 IRQ_MAP(acca_input),
\r
219 acca_overflow_handler:
\r
220 IRQ_MAP(acca_overflow),
\r
221 timer_overflow_handler:
\r
222 IRQ_MAP(timer_overflow),
\r
224 // InputCapture/OutputCompare Timers
\r
242 // External Interrupts
\r
259 IRQ_MAP(cop_clock),
\r