basic interrupt approach succeded, buttons (extint) working perfectly from
[my-code/arm.git] / betty / interrupts.c
1 /*
2  * interrupts.c - arm exception handling
3  *
4  * author: hackbard@hackdaworld.org
5  *
6  */
7
8 #include "interrupts.h"
9 #include "functions.h"
10
11 // 'module global' interrupt variable
12 static t_interrupt interrupt;
13
14 /*
15  * functions
16  */
17
18 void interrupt_init(void) {
19
20         interrupt.default_soft_callback=0;
21         VICSoftIntClr=0xffffffff;
22         VICIntEnClr=0xffffffff;
23         VICDefVectAddr=0;
24 }
25
26 void interrupt_set_default_callback(u32 callback_addr) {
27
28         VICDefVectAddr=callback_addr;
29 }
30
31 void interrupt_set_soft_callback(void (*callback)(void)) {
32
33         interrupt.default_soft_callback=callback;
34 }
35
36 void interrupt_soft_clear(u8 src_number) {
37
38         VICSoftIntClr=(1<<src_number);
39 }
40 void interrupt_clear(u8 src_number) {
41
42         int cnt;
43         u32 *addr;
44         u32 *cntl;
45
46         VICIntEnClr=(1<<src_number);
47         VICIntSelect&=~(1<<src_number);
48
49         addr=(u32 *)&VICVectAddr0;
50         cntl=(u32 *)&VICVectCntl0;
51
52         for(cnt=0;cnt<INTERRUPT_MAX_VIC;cnt++) {
53                 if((cntl[cnt]&0x1f)==src_number) {
54                         *((volatile u32 *)(addr+cnt))=0;
55                         *((volatile u32 *)(cntl+cnt))=0;
56                 }
57         }
58 }
59
60 void interrupt_soft_enable(u8 src_number) {
61         
62         VICSoftInt=(1<<src_number);
63 }
64
65 int interrupt_enable(u8 src_number,u8 mode,u8 priority,u32 callback_addr) {
66
67         u32 *addr;
68         u32 *cntl;
69
70         addr=(u32 *)&VICVectAddr0;
71         cntl=(u32 *)&VICVectCntl0;
72
73         /* check whether this ir source is allready assigned */
74         if(VICIntEnable&(1<<src_number))
75                 return INTERRUPT_USED;
76
77         /* prepare depending on mode */
78         switch(mode) {
79                 case INTERRUPT_MODE_FIQ:
80                         VICIntSelect|=(1<<src_number);
81                         break;
82                 case INTERRUPT_MODE_VIRQ:
83                         if(addr[priority]&0x3f)
84                                 return INTERRUPT_PRIORITY_USED;
85                         *((volatile u32 *)(addr+priority))=callback_addr;
86                         *((volatile u32 *)(cntl+priority))=(src_number&0x1f)+0x20;
87                 case INTERRUPT_MODE_IRQ:
88                 default:
89                         break;
90         }
91
92         /* force interrupt */
93         VICIntEnable=(1<<src_number);
94
95         return INTERRUPT_SET;
96 }
97
98 int interrupt_change_callback(u8 src_number,u32 callback) {
99
100         int i;
101         u32 *addr,*cntl;
102
103         cntl=(u32 *)&VICVectCntl0;
104         addr=(u32 *)&VICVectAddr0;
105
106         i=0;
107         while(i<INTERRUPT_MAX_VIC) {
108                 if((*cntl&0x1f)==src_number) {
109                         *(addr+i)=callback;
110                         return INTERRUPT_CALLBACK_CHANGED;
111                 }
112                 i++;
113         }
114
115         return INTERRUPT_SRC_NOT_USED;
116 }
117
118 void interrupt_ext_ir_config(u8 eint,u8 wakeup,u8 mode,u8 polarity) {
119
120         if(eint>3)
121                 return;
122
123         if(wakeup)
124                 EXTWAKE=(EXTWAKE&0xf)|(1<<eint);
125
126         EXTMODE=(EXTMODE&0xf)|(mode<<eint);
127         EXTPOLAR=(EXTPOLAR&0xf)|(polarity<<eint);
128 }
129
130 void interrupt_ext_ir_set(u8 eint) {
131
132         if(eint>3)
133                 return;
134
135         EXTINT=(1<<eint);
136 }
137
138 void interrupt_ack(void) {
139
140         VICVectAddr=0;
141 }
142
143 /*
144  * the actual exception handlers (as defined in startup.s)
145  */
146
147 // reset
148 void interrupt_handler_reset(void) {
149 }
150
151 // undefined instruction
152 void interrupt_handler_undef_instruction(void) {
153 }
154
155 // software interrupt
156 void interrupt_handler_soft_ir(void) {
157         
158         if(interrupt.default_soft_callback)
159                 interrupt.default_soft_callback();
160 }
161
162 // prefetch abort
163 void interrupt_handler_prefetch_abort(void) {
164 }
165
166 // data abort
167 void interrupt_handler_data_abort(void) {
168 }
169
170 // fiq
171 void interrupt_handler_fiq(void) {
172 }
173