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