1 /*
2 * File : interrupt.c
3 * This file is part of RT-Thread RTOS
4 * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Change Logs:
21 * Date Author Notes
22 * 2013-7-14 Peng Fan sep6200 implementation
23 */
24
25 #include <rtthread.h>
26 #include <rthw.h>
27 #include <sep6200.h>
28
29 #define MAX_HANDLERS 64
30
31
32 #define SEP6200_IRQ_TYPE 0
33 #define SEP6200_FIQ_TYPE 1
34
35 #define int_enable_all() \
36 do { \
37 *(volatile unsigned long*)SEP6200_VIC_INT_EN_L = ~0x0;\
38 *(volatile unsigned long*)SEP6200_VIC_INT_EN_H = ~0x0;\
39 }while(0)
40 #define int_disable_all() \
41 do { \
42 *(volatile unsigned long*)SEP6200_VIC_INT_EN_L = 0x0;\
43 *(volatile unsigned long*)SEP6200_VIC_INT_EN_H = 0x0;\
44 }while(0)
45 #define mask_all_int(int_type) \
46 do { \
47 if (int_type == SEP6200_IRQ_TYPE){ \
48 *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = 0x1;\
49 } else if (int_type == SEP6200_FIQ_TYPE) {\
50 *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = 0x2;\
51 }\
52 }while(0)
53 #define unmask_all_int(int_type)\
54 do { \
55 if (int_type == SEP6200_IRQ_TYPE){ \
56 *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = ~0x1;\
57 } else if (int_type == SEP6200_FIQ_TYPE) {\
58 *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = ~0x2;\
59 }\
60 }while(0)
61
62 #define SEP6200_INT_SET(intnum) \
63 do{ \
64 if(intnum < 32) \
65 *(volatile unsigned long*)SEP6200_VIC_SFT_INT_L |= (1 << intnum); \
66 else \
67 *(volatile unsigned long*)SEP6200_VIC_SFT_INT_H |= (1 << (intnum - 32)); \
68 }while(0)
69
70 #define SEP6200_INT_CLR(intnum) \
71 do{ \
72 if(intnum < 32) \
73 *(volatile unsigned long*)SEP6200_VIC_SFT_INT_L &= ~(1 << intnum);\
74 else \
75 *(volatile unsigned long*)SEP6200_VIC_SFT_INT_H &= ~(1 << (intnum - 32)); \
76 }while(0)
77
78 #define SEP6200_INT_ENABLE(intnum)\
79 do{ \
80 if(intnum < 32) \
81 *(volatile unsigned long*)SEP6200_VIC_INT_EN_L |= (1 << intnum); \
82 else \
83 *(volatile unsigned long*)SEP6200_VIC_INT_EN_H |= (1 << (intnum - 32)); \
84 }while(0)
85
86 #define SEP6200_INT_DISABLE(intnum) \
87 do{ \
88 if(intnum < 32) \
89 *(volatile unsigned long*)SEP6200_VIC_INT_EN_L &= ~(1 << intnum); \
90 else \
91 *(volatile unsigned long*)SEP6200_VIC_INT_EN_H &= ~(1 << (intnum - 32)); \
92 }while(0)
93
94
95 extern rt_uint32_t rt_interrupt_nest;
96 /* exception and interrupt handler table */
97 struct rt_irq_desc isr_table[MAX_HANDLERS];
98 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
99 rt_uint32_t rt_thread_switch_interrupt_flag;
100
101
102 /* --------------------------------------------------------------------
103 * Interrupt initialization
104 * -------------------------------------------------------------------- */
105
106 /**
107 * @addtogroup sep6200
108 */
109 /*@{*/
110
111 void rt_hw_interrupt_mask(int irq);
112 void rt_hw_interrupt_umask(int irq);
113
sep6200_irq_enable(rt_uint32_t irq)114 rt_inline void sep6200_irq_enable(rt_uint32_t irq)
115 {
116 SEP6200_INT_ENABLE(irq);
117 }
118
sep6200_irq_disable(rt_uint32_t irq)119 rt_inline void sep6200_irq_disable(rt_uint32_t irq)
120 {
121 SEP6200_INT_DISABLE(irq);
122 }
123
sep6200_irq_unmask(rt_uint32_t irq)124 rt_inline void sep6200_irq_unmask(rt_uint32_t irq)
125 {
126 SEP6200_INT_ENABLE(irq);
127 }
128
sep6200_irq_mask(rt_uint32_t irq)129 rt_inline void sep6200_irq_mask(rt_uint32_t irq)
130 {
131 SEP6200_INT_DISABLE(irq);
132 }
rt_hw_interrupt_handle(rt_uint32_t vector)133 rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector)
134 {
135 rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
136 return RT_NULL;
137 }
138
139 /**
140 * This function will initialize hardware interrupt
141 */
rt_hw_interrupt_init(void)142 void rt_hw_interrupt_init(void)
143 {
144 rt_int32_t i;
145 register rt_uint32_t idx;
146
147
148 /* init exceptions table */
149 for(idx=0; idx < MAX_HANDLERS; idx++)
150 {
151 isr_table[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
152 }
153 int_disable_all();
154 mask_all_int(SEP6200_FIQ_TYPE);
155
156 //int_enable_all();
157 unmask_all_int(SEP6200_IRQ_TYPE);
158
159 /* init interrupt nest, and context in thread sp */
160 rt_interrupt_nest = 0;
161 rt_interrupt_from_thread = 0;
162 rt_interrupt_to_thread = 0;
163 rt_thread_switch_interrupt_flag = 0;
164 }
165
166
167
168 /**
169 * This function will mask a interrupt.
170 * @param vector the interrupt number
171 */
rt_hw_interrupt_mask(int irq)172 void rt_hw_interrupt_mask(int irq)
173 {
174 if (irq >= MAX_HANDLERS) {
175 rt_kprintf("Wrong irq num to mask\n");
176 } else {
177 sep6200_irq_mask(irq);
178 }
179
180 }
181
182 /**
183 * This function will un-mask a interrupt.
184 * @param vector the interrupt number
185 */
rt_hw_interrupt_umask(int irq)186 void rt_hw_interrupt_umask(int irq)
187 {
188 if (irq >= MAX_HANDLERS) {
189 rt_kprintf("Wrong irq num to unmask\n");
190 } else {
191 sep6200_irq_unmask(irq);
192 }
193 }
194
195 /**
196 * This function will install a interrupt service routine to a interrupt.
197 * @param vector the interrupt number
198 * @param new_handler the interrupt service routine to be installed
199 * @param old_handler the old interrupt service routine
200 */
rt_hw_interrupt_install(int vector,rt_isr_handler_t handler,void * param,const char * name)201 rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
202 void *param, const char *name)
203 {
204 rt_isr_handler_t old_handler = RT_NULL;
205
206 if(vector < MAX_HANDLERS)
207 {
208 old_handler = isr_table[vector].handler;
209
210 if (handler != RT_NULL)
211 {
212 #ifdef RT_USING_INTERRUPT_INFO
213 rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
214 #endif /* RT_USING_INTERRUPT_INFO */
215 isr_table[vector].handler = handler;
216 isr_table[vector].param = param;
217 }
218 }
219
220 return old_handler;
221 }
222
223 /*@}*/
224