sysirq_at91.c

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