1
0

interrupt.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. #include <rtthread.h>
  25. #include <rthw.h>
  26. #include <sep6200.h>
  27. #define MAX_HANDLERS 64
  28. #define SEP6200_IRQ_TYPE 0
  29. #define SEP6200_FIQ_TYPE 1
  30. #define int_enable_all() \
  31. do { \
  32. *(volatile unsigned long*)SEP6200_VIC_INT_EN_L = ~0x0;\
  33. *(volatile unsigned long*)SEP6200_VIC_INT_EN_H = ~0x0;\
  34. }while(0)
  35. #define int_disable_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 mask_all_int(int_type) \
  41. do { \
  42. if (int_type == SEP6200_IRQ_TYPE){ \
  43. *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = 0x1;\
  44. } else if (int_type == SEP6200_FIQ_TYPE) {\
  45. *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = 0x2;\
  46. }\
  47. }while(0)
  48. #define unmask_all_int(int_type)\
  49. do { \
  50. if (int_type == SEP6200_IRQ_TYPE){ \
  51. *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = ~0x1;\
  52. } else if (int_type == SEP6200_FIQ_TYPE) {\
  53. *(volatile unsigned long*)SEP6200_VIC_INT_MSK_ALL = ~0x2;\
  54. }\
  55. }while(0)
  56. #define SEP6200_INT_SET(intnum) \
  57. do{ \
  58. if(intnum < 32) \
  59. *(volatile unsigned long*)SEP6200_VIC_SFT_INT_L |= (1 << intnum); \
  60. else \
  61. *(volatile unsigned long*)SEP6200_VIC_SFT_INT_H |= (1 << (intnum - 32)); \
  62. }while(0)
  63. #define SEP6200_INT_CLR(intnum) \
  64. do{ \
  65. if(intnum < 32) \
  66. *(volatile unsigned long*)SEP6200_VIC_SFT_INT_L &= ~(1 << intnum);\
  67. else \
  68. *(volatile unsigned long*)SEP6200_VIC_SFT_INT_H &= ~(1 << (intnum - 32)); \
  69. }while(0)
  70. #define SEP6200_INT_ENABLE(intnum)\
  71. do{ \
  72. if(intnum < 32) \
  73. *(volatile unsigned long*)SEP6200_VIC_INT_EN_L |= (1 << intnum); \
  74. else \
  75. *(volatile unsigned long*)SEP6200_VIC_INT_EN_H |= (1 << (intnum - 32)); \
  76. }while(0)
  77. #define SEP6200_INT_DISABLE(intnum) \
  78. do{ \
  79. if(intnum < 32) \
  80. *(volatile unsigned long*)SEP6200_VIC_INT_EN_L &= ~(1 << intnum); \
  81. else \
  82. *(volatile unsigned long*)SEP6200_VIC_INT_EN_H &= ~(1 << (intnum - 32)); \
  83. }while(0)
  84. extern rt_uint32_t rt_interrupt_nest;
  85. /* exception and interrupt handler table */
  86. struct rt_irq_desc isr_table[MAX_HANDLERS];
  87. rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
  88. rt_uint32_t rt_thread_switch_interrupt_flag;
  89. /* --------------------------------------------------------------------
  90. * Interrupt initialization
  91. * -------------------------------------------------------------------- */
  92. /**
  93. * @addtogroup sep6200
  94. */
  95. /*@{*/
  96. void rt_hw_interrupt_mask(int irq);
  97. void rt_hw_interrupt_umask(int irq);
  98. rt_inline void sep6200_irq_enable(rt_uint32_t irq)
  99. {
  100. SEP6200_INT_ENABLE(irq);
  101. }
  102. rt_inline void sep6200_irq_disable(rt_uint32_t irq)
  103. {
  104. SEP6200_INT_DISABLE(irq);
  105. }
  106. rt_inline void sep6200_irq_unmask(rt_uint32_t irq)
  107. {
  108. SEP6200_INT_ENABLE(irq);
  109. }
  110. rt_inline void sep6200_irq_mask(rt_uint32_t irq)
  111. {
  112. SEP6200_INT_DISABLE(irq);
  113. }
  114. rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector)
  115. {
  116. rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
  117. return RT_NULL;
  118. }
  119. /**
  120. * This function will initialize hardware interrupt
  121. */
  122. void rt_hw_interrupt_init(void)
  123. {
  124. rt_int32_t i;
  125. register rt_uint32_t idx;
  126. /* init exceptions table */
  127. for(idx=0; idx < MAX_HANDLERS; idx++)
  128. {
  129. isr_table[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
  130. }
  131. int_disable_all();
  132. mask_all_int(SEP6200_FIQ_TYPE);
  133. //int_enable_all();
  134. unmask_all_int(SEP6200_IRQ_TYPE);
  135. /* init interrupt nest, and context in thread sp */
  136. rt_interrupt_nest = 0;
  137. rt_interrupt_from_thread = 0;
  138. rt_interrupt_to_thread = 0;
  139. rt_thread_switch_interrupt_flag = 0;
  140. }
  141. /**
  142. * This function will mask a interrupt.
  143. * @param vector the interrupt number
  144. */
  145. void rt_hw_interrupt_mask(int irq)
  146. {
  147. if (irq >= MAX_HANDLERS) {
  148. rt_kprintf("Wrong irq num to mask\n");
  149. } else {
  150. sep6200_irq_mask(irq);
  151. }
  152. }
  153. /**
  154. * This function will un-mask a interrupt.
  155. * @param vector the interrupt number
  156. */
  157. void rt_hw_interrupt_umask(int irq)
  158. {
  159. if (irq >= MAX_HANDLERS) {
  160. rt_kprintf("Wrong irq num to unmask\n");
  161. } else {
  162. sep6200_irq_unmask(irq);
  163. }
  164. }
  165. /**
  166. * This function will install a interrupt service routine to a interrupt.
  167. * @param vector the interrupt number
  168. * @param new_handler the interrupt service routine to be installed
  169. * @param old_handler the old interrupt service routine
  170. */
  171. rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
  172. void *param, char *name)
  173. {
  174. rt_isr_handler_t old_handler = RT_NULL;
  175. if(vector < MAX_HANDLERS)
  176. {
  177. old_handler = isr_table[vector].handler;
  178. if (handler != RT_NULL)
  179. {
  180. #ifdef RT_USING_INTERRUPT_INFO
  181. rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
  182. #endif /* RT_USING_INTERRUPT_INFO */
  183. isr_table[vector].handler = handler;
  184. isr_table[vector].param = param;
  185. }
  186. }
  187. return old_handler;
  188. }
  189. /*@}*/