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 
00097 static void sysirq_dispatcher(void) __attribute__ ((interrupt));
00098 static void sysirq_dispatcher(void)
00099 {
00100     for (unsigned i = 0; i < countof(sysirq_tab); i++)
00101     {
00102         if (sysirq_tab[i].enabled
00103          && sysirq_tab[i].handler)
00104             sysirq_tab[i].handler();
00105     }
00106 
00107     /* Inform hw that we have served the IRQ */
00108     AIC_EOICR = 0;
00109 }
00110 
00111 #define SYSIRQ_PRIORITY 0 
00112 
00113 
00114 MOD_DEFINE(sysirq);
00115 
00120 void sysirq_init(void)
00121 {
00122     cpu_flags_t flags;
00123     IRQ_SAVE_DISABLE(flags);
00124 
00125     /* Disable all system interrupts */
00126     for (unsigned i = 0; i < countof(sysirq_tab); i++)
00127         sysirq_tab[i].setEnable(false);
00128 
00129     /* Set the vector. */
00130     AIC_SVR(SYSC_ID) = sysirq_dispatcher;
00131     /* Initialize to edge triggered with defined priority. */
00132     AIC_SMR(SYSC_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SYSIRQ_PRIORITY;
00133     /* Clear pending interrupt */
00134     AIC_ICCR = BV(SYSC_ID);
00135     /* Enable the system IRQ */
00136     AIC_IECR = BV(SYSC_ID);
00137 
00138     IRQ_RESTORE(flags);
00139     MOD_INIT(sysirq);
00140 }
00141 
00142 
00146 void sysirq_setHandler(sysirq_t irq, sysirq_handler_t handler)
00147 {
00148     ASSERT(irq < SYSIRQ_CNT);
00149     sysirq_tab[irq].handler = handler;
00150 }
00151 
00155 void sysirq_setEnable(sysirq_t irq, bool enable)
00156 {
00157     ASSERT(irq < SYSIRQ_CNT);
00158 
00159     sysirq_tab[irq].setEnable(enable);
00160     sysirq_tab[irq].enabled = enable;
00161 }
00162 
00166 bool sysirq_enabled(sysirq_t irq)
00167 {
00168     ASSERT(irq < SYSIRQ_CNT);
00169 
00170     return sysirq_tab[irq].enabled;
00171 }