]> rtime.felk.cvut.cz Git - arc.git/blob - arch/arm/arm_cm3/kernel/irq.c
Inclusion fixes for CM3 kernel
[arc.git] / arch / arm / arm_cm3 / kernel / irq.c
1 /* -------------------------------- Arctic Core ------------------------------
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com
3  *
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
5  *
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>.
9  *
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
13  * for more details.
14  * -------------------------------- Arctic Core ------------------------------*/
15
16 #include "internal.h"
17 #include "task_i.h"
18 #include "hooks.h"
19 #include "stm32f10x.h"
20 #include "irq.h"
21
22 extern void *Irq_VectorTable[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];
23
24 /**
25  * Init NVIC vector. We do not use subpriority
26  *
27  * @param vector        The IRQ number
28  * @param prio      NVIC priority, 0-31, 0-high prio
29  */
30 static void NVIC_InitVector(IRQn_Type vector, uint32_t prio)
31 {
32         // Set prio
33         NVIC_SetPriority(vector,prio);
34
35         // Enable
36     NVIC->ISER[vector >> 5] = (uint32_t)1 << (vector & (uint8_t)0x1F);
37 }
38
39 /*
40 PRIGROUP
41 0                       7.1 indicates seven bits of pre-emption priority, one bit of subpriority
42 1                       6.2 indicates six bits of pre-emption priority, two bits of subpriority
43 2                       5.3 indicates five bits of pre-emption priority, three bits of subpriority
44 3                       4.4 indicates four bits of pre-emption priority, four bits of subpriority
45 4                       3.5 indicates three bits of pre-emption priority, five bits of subpriority
46 5                       2.6 indicates two bits of pre-emption priority, six bits of subpriority
47 6                       1.7 indicates one bit of pre-emption priority, seven bits of subpriority
48 7                       0.8 indicates no pre-emption priority, eight bits of subpriority.
49 */
50 void Irq_Init( void ) {
51         NVIC_SetPriorityGrouping(0);
52         NVIC_SetPriority(SVCall_IRQn, 0xff); // Set lowest prio
53         NVIC_SetPriority(PendSV_IRQn, 0xff); // Set lowest prio
54
55         /* Stop counters and watchdogs when halting in debug */
56         DBGMCU->CR |= 0x00ffffff00;
57 }
58
59 void Irq_EOI( void ) {
60         /* Note!
61          * This is not applicable on the Cortex-M3 since we
62          * can't terminate the interrupt request without popping
63          * back registers..have to be solved in the context switches
64          * themselves.
65          */
66 }
67
68 #define ICSR_VECTACTIVE         0x1ff
69
70 /**
71  * Get Active ISR number field.
72  * You can subtract 16 from the VECTACTIVE field to index into the Interrupt
73  * Clear/Set Enable, Interrupt Clear Pending/SetPending and Interrupt Priority
74  * Registers. INTISR[0] has vector number 16.
75  *
76  */
77 static uint32_t NVIC_GetActiveVector( void) {
78         return (SCB->ICSR &  ICSR_VECTACTIVE);
79 }
80
81
82 /**
83  *
84  * @param stack_p Ptr to the current stack.
85  *
86  * The stack holds C, NVGPR, VGPR and the EXC frame.
87  *
88  */
89 void *Irq_Entry( void *stack_p ){
90         uint32_t vector = 0;
91
92         Irq_Disable();
93
94         /* 0. Set the default handler here....
95          * 1. Grab the vector from the interrupt controller
96          *    INT_CTRL_ST[VECTACTIVE]
97          * 2. Irq_VectorTable[vector] is odd -> ISR1
98          *    Irq_VectorTable[vector] is even-> ISR2
99          */
100
101
102         vector = NVIC_GetActiveVector();
103
104         Os_Isr_cm3((void *)Irq_VectorTable[vector]);
105         Irq_Enable();
106
107         return stack_p;
108 }
109
110 /**
111  * Attach an ISR type 1 to the interrupt controller.
112  *
113  * @param entry
114  * @param int_ctrl
115  * @param vector
116  * @param prio
117  */
118 void Irq_AttachIsr1( void (*entry)(void), void *int_ctrl, uint32_t vector, uint8_t prio) {
119
120         // TODO: Use NVIC_InitVector(vector, osPrioToCpuPio(pcb->prio)); here
121 }
122
123 /**
124  * NVIC prio have priority 0-31, 0-highest priority.
125  * Autosar does it the other way around, 0-Lowest priority
126  * NOTE: prio 255 is reserved for SVC and PendSV
127  *
128  * Autosar    NVIC
129  *   31        0
130  *   30        1
131  *   ..
132  *   0         31
133  * @param prio
134  * @return
135  */
136 static inline int osPrioToCpuPio( uint8_t prio ) {
137         assert(prio<32);
138         prio = 31 - prio;
139         return prio;
140 }
141
142 /**
143  * Attach a ISR type 2 to the interrupt controller.
144  *
145  * @param tid
146  * @param int_ctrl
147  * @param vector
148  */
149 void Irq_AttachIsr2(TaskType tid,void *int_ctrl,IrqType vector ) {
150         OsPcbType *pcb;
151
152         pcb = os_find_task(tid);
153         Irq_VectorTable[vector+16] = (void *)pcb;
154
155         NVIC_InitVector(vector, osPrioToCpuPio(pcb->prio));
156 }
157
158
159 /**
160  * Generates a soft interrupt, ie sets pending bit.
161  * This could also be implemented using ISPR regs.
162  *
163  * @param vector
164  */
165 void Irq_GenerateSoftInt( IrqType vector ) {
166
167         NVIC->STIR = (vector);
168 }
169
170 /**
171  * Get the current priority from the interrupt controller.
172  * @param cpu
173  * @return
174  */
175 uint8_t Irq_GetCurrentPriority( Cpu_t cpu) {
176
177         uint8_t prio = 0;
178
179         // SCB_ICSR contains the active vector
180         return prio;
181 }
182
183 typedef struct {
184         uint32_t dummy;
185 } exc_stack_t;
186
187