Contiki 2.6
|
00001 #include <sys-interrupt.h> 00002 #include <interrupt-utils.h> 00003 #include <AT91SAM7S64.h> 00004 00005 #define ATTR 00006 00007 #ifndef NULL 00008 #define NULL 0 00009 #endif 00010 00011 00012 static SystemInterruptHandler *handlers = NULL; 00013 00014 static void 00015 system_int_safe (void) __attribute__((noinline)); 00016 00017 static void 00018 system_int_safe (void) 00019 { 00020 SystemInterruptHandler *h; 00021 h = handlers; 00022 while (h) { 00023 if (h->handler()) break; 00024 h = h->next; 00025 } 00026 } 00027 00028 static void NACKEDFUNC ATTR 00029 system_int (void) /* System Interrupt Handler */ 00030 { 00031 ISR_ENTRY(); 00032 system_int_safe(); 00033 *AT91C_AIC_EOICR = 0; /* End of Interrupt */ 00034 ISR_EXIT(); 00035 } 00036 00037 static unsigned int enabled = 0; /* Number of times the system 00038 interrupt has been enabled */ 00039 00040 #define DIS_INT *AT91C_AIC_IDCR = (1 << AT91C_ID_SYS) 00041 #define EN_INT if (enabled > 0) *AT91C_AIC_IECR = (1 << AT91C_ID_SYS) 00042 00043 void 00044 sys_interrupt_enable() 00045 { 00046 if (enabled++ == 0) { 00047 /* Level trigged at priority 5 */ 00048 AT91C_AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5; 00049 /* Interrupt vector */ 00050 AT91C_AIC_SVR[AT91C_ID_SYS] = (unsigned long) system_int; 00051 /* Enable */ 00052 EN_INT; 00053 } 00054 } 00055 00056 00057 void 00058 sys_interrupt_disable() 00059 { 00060 if (--enabled == 0) { 00061 DIS_INT; 00062 } 00063 } 00064 00065 void 00066 sys_interrupt_append_handler(SystemInterruptHandler *handler) 00067 { 00068 SystemInterruptHandler **h = &handlers; 00069 while(*h) { 00070 h = &(*h)->next; 00071 } 00072 DIS_INT; 00073 *h = handler; 00074 handler->next = NULL; 00075 EN_INT; 00076 } 00077 00078 void 00079 sys_interrupt_prepend_handler(SystemInterruptHandler *handler) 00080 { 00081 DIS_INT; 00082 handler->next = handlers; 00083 handlers = handler; 00084 EN_INT; 00085 } 00086 00087 void 00088 sys_interrupt_remove_handler(SystemInterruptHandler *handler) 00089 { 00090 SystemInterruptHandler **h = &handlers; 00091 while(*h) { 00092 if (*h == handler) { 00093 DIS_INT; 00094 *h = handler->next; 00095 EN_INT; 00096 break; 00097 } 00098 h = &(*h)->next; 00099 } 00100 }