xref: /nrf52832-nimble/rt-thread/libcpu/unicore32/sep6200/interrupt.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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 
114 rt_inline void sep6200_irq_enable(rt_uint32_t irq)
115 {
116 	SEP6200_INT_ENABLE(irq);
117 }
118 
119 rt_inline void sep6200_irq_disable(rt_uint32_t irq)
120 {
121 	SEP6200_INT_DISABLE(irq);
122 }
123 
124 rt_inline void sep6200_irq_unmask(rt_uint32_t irq)
125 {
126 	SEP6200_INT_ENABLE(irq);
127 }
128 
129 rt_inline void sep6200_irq_mask(rt_uint32_t irq)
130 {
131 	SEP6200_INT_DISABLE(irq);
132 }
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  */
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  */
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  */
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  */
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