1
0

interrupt.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * File : interrupt.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://openlab.rt-thread.com/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2011-01-13 weety first version
  13. */
  14. #include <rtthread.h>
  15. #include "at91sam926x.h"
  16. #define MAX_HANDLERS 32
  17. extern rt_uint32_t rt_interrupt_nest;
  18. /* exception and interrupt handler table */
  19. rt_isr_handler_t isr_table[MAX_HANDLERS];
  20. rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
  21. rt_uint32_t rt_thread_switch_interrput_flag;
  22. /* --------------------------------------------------------------------
  23. * Interrupt initialization
  24. * -------------------------------------------------------------------- */
  25. rt_uint32_t at91_extern_irq;
  26. #define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq)
  27. /*
  28. * The default interrupt priority levels (0 = lowest, 7 = highest).
  29. */
  30. static rt_uint32_t at91sam9260_default_irq_priority[MAX_HANDLERS] = {
  31. 7, /* Advanced Interrupt Controller */
  32. 7, /* System Peripherals */
  33. 1, /* Parallel IO Controller A */
  34. 1, /* Parallel IO Controller B */
  35. 1, /* Parallel IO Controller C */
  36. 0, /* Analog-to-Digital Converter */
  37. 5, /* USART 0 */
  38. 5, /* USART 1 */
  39. 5, /* USART 2 */
  40. 0, /* Multimedia Card Interface */
  41. 2, /* USB Device Port */
  42. 6, /* Two-Wire Interface */
  43. 5, /* Serial Peripheral Interface 0 */
  44. 5, /* Serial Peripheral Interface 1 */
  45. 5, /* Serial Synchronous Controller */
  46. 0,
  47. 0,
  48. 0, /* Timer Counter 0 */
  49. 0, /* Timer Counter 1 */
  50. 0, /* Timer Counter 2 */
  51. 2, /* USB Host port */
  52. 3, /* Ethernet */
  53. 0, /* Image Sensor Interface */
  54. 5, /* USART 3 */
  55. 5, /* USART 4 */
  56. 5, /* USART 5 */
  57. 0, /* Timer Counter 3 */
  58. 0, /* Timer Counter 4 */
  59. 0, /* Timer Counter 5 */
  60. 0, /* Advanced Interrupt Controller */
  61. 0, /* Advanced Interrupt Controller */
  62. 0, /* Advanced Interrupt Controller */
  63. };
  64. /**
  65. * @addtogroup AT91SAM926X
  66. */
  67. /*@{*/
  68. rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector)
  69. {
  70. rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
  71. return RT_NULL;
  72. }
  73. /*
  74. * Initialize the AIC interrupt controller.
  75. */
  76. void at91_aic_init(rt_uint32_t *priority)
  77. {
  78. rt_uint32_t i;
  79. /*
  80. * The IVR is used by macro get_irqnr_and_base to read and verify.
  81. * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred.
  82. */
  83. for (i = 0; i < MAX_HANDLERS; i++) {
  84. /* Put irq number in Source Vector Register: */
  85. at91_sys_write(AT91_AIC_SVR(i), i);
  86. /* Active Low interrupt, with the specified priority */
  87. at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]);
  88. //AT91_AIC_SRCTYPE_FALLING
  89. /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
  90. if (i < 8)
  91. at91_sys_write(AT91_AIC_EOICR, 0);
  92. }
  93. /*
  94. * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS
  95. * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
  96. */
  97. at91_sys_write(AT91_AIC_SPU, MAX_HANDLERS);
  98. /* No debugging in AIC: Debug (Protect) Control Register */
  99. at91_sys_write(AT91_AIC_DCR, 0);
  100. /* Disable and clear all interrupts initially */
  101. at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF);
  102. at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF);
  103. }
  104. /**
  105. * This function will initialize hardware interrupt
  106. */
  107. void rt_hw_interrupt_init(void)
  108. {
  109. rt_int32_t i;
  110. register rt_uint32_t idx;
  111. rt_uint32_t *priority = at91sam9260_default_irq_priority;
  112. at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
  113. | (1 << AT91SAM9260_ID_IRQ2);
  114. /* Initialize the AIC interrupt controller */
  115. at91_aic_init(priority);
  116. /* init exceptions table */
  117. for(idx=0; idx < MAX_HANDLERS; idx++)
  118. {
  119. isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handle;
  120. }
  121. /* init interrupt nest, and context in thread sp */
  122. rt_interrupt_nest = 0;
  123. rt_interrupt_from_thread = 0;
  124. rt_interrupt_to_thread = 0;
  125. rt_thread_switch_interrput_flag = 0;
  126. }
  127. /**
  128. * This function will mask a interrupt.
  129. * @param vector the interrupt number
  130. */
  131. void rt_hw_interrupt_mask(int irq)
  132. {
  133. /* Disable interrupt on AIC */
  134. at91_sys_write(AT91_AIC_IDCR, 1 << irq);
  135. }
  136. /**
  137. * This function will un-mask a interrupt.
  138. * @param vector the interrupt number
  139. */
  140. void rt_hw_interrupt_umask(int irq)
  141. {
  142. /* Enable interrupt on AIC */
  143. at91_sys_write(AT91_AIC_IECR, 1 << irq);
  144. }
  145. /**
  146. * This function will install a interrupt service routine to a interrupt.
  147. * @param vector the interrupt number
  148. * @param new_handler the interrupt service routine to be installed
  149. * @param old_handler the old interrupt service routine
  150. */
  151. void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
  152. {
  153. if(vector < MAX_HANDLERS)
  154. {
  155. if (*old_handler != RT_NULL) *old_handler = isr_table[vector];
  156. if (new_handler != RT_NULL) isr_table[vector] = new_handler;
  157. }
  158. }
  159. /*@}*/
  160. static int at91_aic_set_type(unsigned irq, unsigned type)
  161. {
  162. unsigned int smr, srctype;
  163. switch (type) {
  164. case IRQ_TYPE_LEVEL_HIGH:
  165. srctype = AT91_AIC_SRCTYPE_HIGH;
  166. break;
  167. case IRQ_TYPE_EDGE_RISING:
  168. srctype = AT91_AIC_SRCTYPE_RISING;
  169. break;
  170. case IRQ_TYPE_LEVEL_LOW:
  171. if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */
  172. srctype = AT91_AIC_SRCTYPE_LOW;
  173. else
  174. return -1;
  175. break;
  176. case IRQ_TYPE_EDGE_FALLING:
  177. if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */
  178. srctype = AT91_AIC_SRCTYPE_FALLING;
  179. else
  180. return -1;
  181. break;
  182. default:
  183. return -1;
  184. }
  185. smr = at91_sys_read(AT91_AIC_SMR(irq)) & ~AT91_AIC_SRCTYPE;
  186. at91_sys_write(AT91_AIC_SMR(irq), smr | srctype);
  187. return 0;
  188. }