BeRTOS
sysirq_at91.c
Go to the documentation of this file.
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 }