BeRTOS
|
00001 00054 #include "sysirq_at91.h" 00055 #include <io/arm.h> 00056 #include <cpu/irq.h> 00057 #include <cpu/types.h> 00058 #include <cfg/module.h> 00059 #include <cfg/macros.h> 00060 00065 INLINE void pit_setEnable(bool enable) 00066 { 00067 if (enable) 00068 PIT_MR |= BV(PITIEN); 00069 else 00070 PIT_MR &= ~BV(PITIEN); 00071 } 00072 00076 static SysIrq sysirq_tab[] = 00077 { 00078 /* PIT, Periodic Interval Timer (System timer)*/ 00079 { 00080 .enabled = false, 00081 .setEnable = pit_setEnable, 00082 .handler = NULL, 00083 }, 00084 /* TODO: add other system sources here */ 00085 }; 00086 00087 STATIC_ASSERT(countof(sysirq_tab) == SYSIRQ_CNT); 00088 00101 static DECLARE_ISR_CONTEXT_SWITCH(sysirq_dispatcher) 00102 { 00103 unsigned int i; 00104 00105 for (i = 0; i < countof(sysirq_tab); i++) 00106 { 00107 if (sysirq_tab[i].enabled 00108 && sysirq_tab[i].handler) 00109 sysirq_tab[i].handler(); 00110 } 00111 00112 /* Inform hw that we have served the IRQ */ 00113 AIC_EOICR = 0; 00114 } 00115 00116 #define SYSIRQ_PRIORITY 0 ///< default priority for system irqs. 00117 00118 00119 MOD_DEFINE(sysirq); 00120 00125 void sysirq_init(void) 00126 { 00127 cpu_flags_t flags; 00128 IRQ_SAVE_DISABLE(flags); 00129 00130 /* Disable all system interrupts */ 00131 for (unsigned i = 0; i < countof(sysirq_tab); i++) 00132 sysirq_tab[i].setEnable(false); 00133 00134 /* Set the vector. */ 00135 AIC_SVR(SYSC_ID) = sysirq_dispatcher; 00136 /* Initialize to edge triggered with defined priority. */ 00137 AIC_SMR(SYSC_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SYSIRQ_PRIORITY; 00138 /* Clear pending interrupt */ 00139 AIC_ICCR = BV(SYSC_ID); 00140 /* Enable the system IRQ */ 00141 AIC_IECR = BV(SYSC_ID); 00142 00143 IRQ_RESTORE(flags); 00144 MOD_INIT(sysirq); 00145 } 00146 00147 00151 void sysirq_setHandler(sysirq_t irq, sysirq_handler_t handler) 00152 { 00153 ASSERT(irq < SYSIRQ_CNT); 00154 sysirq_tab[irq].handler = handler; 00155 } 00156 00160 void sysirq_setEnable(sysirq_t irq, bool enable) 00161 { 00162 ASSERT(irq < SYSIRQ_CNT); 00163 00164 sysirq_tab[irq].setEnable(enable); 00165 sysirq_tab[irq].enabled = enable; 00166 } 00167 00171 bool sysirq_enabled(sysirq_t irq) 00172 { 00173 ASSERT(irq < SYSIRQ_CNT); 00174 00175 return sysirq_tab[irq].enabled; 00176 }