Contiki 2.5
sys-interrupt.c
1 #include <sys-interrupt.h>
2 #include <interrupt-utils.h>
3 #include <AT91SAM7S64.h>
4 
5 #define ATTR
6 
7 #ifndef NULL
8 #define NULL 0
9 #endif
10 
11 
12 static SystemInterruptHandler *handlers = NULL;
13 
14 static void
15 system_int_safe (void) __attribute__((noinline));
16 
17 static void
18 system_int_safe (void)
19 {
20  SystemInterruptHandler *h;
21  h = handlers;
22  while (h) {
23  if (h->handler()) break;
24  h = h->next;
25  }
26 }
27 
28 static void NACKEDFUNC ATTR
29 system_int (void) /* System Interrupt Handler */
30 {
31  ISR_ENTRY();
32  system_int_safe();
33  *AT91C_AIC_EOICR = 0; /* End of Interrupt */
34  ISR_EXIT();
35 }
36 
37 static unsigned int enabled = 0; /* Number of times the system
38  interrupt has been enabled */
39 
40 #define DIS_INT *AT91C_AIC_IDCR = (1 << AT91C_ID_SYS)
41 #define EN_INT if (enabled > 0) *AT91C_AIC_IECR = (1 << AT91C_ID_SYS)
42 
43 void
44 sys_interrupt_enable()
45 {
46  if (enabled++ == 0) {
47  /* Level trigged at priority 5 */
48  AT91C_AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
49  /* Interrupt vector */
50  AT91C_AIC_SVR[AT91C_ID_SYS] = (unsigned long) system_int;
51  /* Enable */
52  EN_INT;
53  }
54 }
55 
56 
57 void
58 sys_interrupt_disable()
59 {
60  if (--enabled == 0) {
61  DIS_INT;
62  }
63 }
64 
65 void
66 sys_interrupt_append_handler(SystemInterruptHandler *handler)
67 {
68  SystemInterruptHandler **h = &handlers;
69  while(*h) {
70  h = &(*h)->next;
71  }
72  DIS_INT;
73  *h = handler;
74  handler->next = NULL;
75  EN_INT;
76 }
77 
78 void
79 sys_interrupt_prepend_handler(SystemInterruptHandler *handler)
80 {
81  DIS_INT;
82  handler->next = handlers;
83  handlers = handler;
84  EN_INT;
85 }
86 
87 void
88 sys_interrupt_remove_handler(SystemInterruptHandler *handler)
89 {
90  SystemInterruptHandler **h = &handlers;
91  while(*h) {
92  if (*h == handler) {
93  DIS_INT;
94  *h = handler->next;
95  EN_INT;
96  break;
97  }
98  h = &(*h)->next;
99  }
100 }