first button test using interrupts (untested!)
[my-code/arm.git] / betty / interrupts.c
index 61cf1af..49ea0cd 100644 (file)
 
 #include "interrupts.h"
 
+// 'module global' interrupt variable
+static t_interrupt interrupt;
+
 /*
  * functions
  */
 
-void interrupt_set_default_callback(t_interrupt *ir,void *callback) {
+void interrupt_init(void) {
+
+       memset(&interrupt,0,sizeof(t_interrupt));
+       VICSoftIntClear=0xff;
+       VICIntEnClear=0xff;
+       VICDefVectAddr=0;
+}
+
+void interrupt_set_default_callback(u32 callback_addr) {
+
+       VICDefVectAddr=callback_addr;
+}
+
+void interrupt_set_soft_callback(void (*callback)(void)) {
+
+       interrupt->default_soft_callback=callback;
+}
+
+void interrupt_soft_clear(u8 src_number) {
+
+       VICSoftIntClear=(1<<src_number);
+}
+void interrupt_clear(u8 src_number) {
+
+       int cnt;
+       u32 *addr;
+       u32 *cntl;
+
+       VICIntEnClear=(1<<src_number);
+       VICIntSelect&=~(1<<src_number);
 
-       ir->default_callback=callback;
+       addr=&VICVectAddr0;
+       cntl=&VICVectCntl0;
+
+       for(cnt=0;cnt<INTERRUPT_MAX_VIC;cnt++) {
+               if(cntl[cnt]&0x1f==src_number) {
+                       *((volatile u32 *)(addr+cnt))=0;
+                       *((volatile u32 *)(cntl+cnt))=0;
+               }
+       }
+}
+
+void interrupt_soft_enable(u8 src_number) {
+       
+       VICSoftInt=(1<<src_number);
+}
+
+int interrupt_enable(u8 src_number,u8 mode,u8 priority,u32 callback_addr) {
+
+       u32 *addr;
+       u32 *cntl;
+
+       addr=&VICVectAddr0;
+       cntl=&VICVectCntl0;
+
+       /* check whether this ir source is allready assigned */
+       if(VICIntEnable&(1<<src_number))
+               return INTERRUPT_USED;
+
+       /* force interrupt */
+       VICIntEnable=(1<<src_number);
+
+       switch(mode) {
+               case INTERRUPT_MODE_FIQ:
+                       VICIntSelect|=(1<<src_number);
+                       break;
+               case INTERRUPT_MODE_VIRQ:
+                       if(addr[p]&0x3f)
+                               return INTERRUP_PRIORITY_USED;
+                       *((volatile u32 *)(addr+p))=callback_addr;
+                       *((volatile u32 *)(cntl+p))=src_number&0x1f+(1<<5);
+               case INTERRUPT_MODE_IRQ:
+               case default:
+       }
+
+       return INTERRUPT_SET;
 }
 
+void interrupt_ext_ir_config(u8 eint,u8 wakeup,u8 mode,u8 polarity) {
 
+       if(eint>3)
+               return;
+
+       if(wakeup)
+               EXTWAKE=(EXTWAKE&0xf)|(1<<eint);
+
+       EXTMODE=(EXTMODE&0xf)|(mode<<eint);
+       EXTPOLAR=(EXTPOLAR&0xf)|(polarity<<eint);
+       EXTINT=(EXTINT&0xf)|(1<<eint);
+}
 
 /*
  * the actual exception handlers (as defined in startup.s)
@@ -32,6 +119,9 @@ void interrupt_handler_undef_instruction(void) {
 
 // software interrupt
 void interrupt_handler_soft_ir(void) {
+       
+       if(interrupt.default_soft_callback)
+               interrupt.default_soft_callback();
 }
 
 // prefetch abort