2 * interrupts.c - arm exception handling
4 * author: hackbard@hackdaworld.org
8 #include "interrupts.h"
11 // 'module global' interrupt variable
12 static t_interrupt interrupt;
18 // generaal interrupt handling
20 void interrupt_init(void) {
22 interrupt.default_soft_callback=0;
23 VICSoftIntClr=0xffffffff;
24 VICIntEnClr=0xffffffff;
28 void interrupt_set_default_callback(u32 callback_addr) {
30 VICDefVectAddr=callback_addr;
33 void interrupt_set_soft_callback(void (*callback)(void)) {
35 interrupt.default_soft_callback=callback;
38 void interrupt_set_fiq_callback(void (*callback)(void)) {
40 interrupt.fiq_callback=callback;
43 void interrupt_soft_clear(u8 src_number) {
45 VICSoftIntClr=(1<<src_number);
47 void interrupt_clear(u8 src_number) {
53 VICIntEnClr=(1<<src_number);
54 VICIntSelect&=~(1<<src_number);
56 addr=(u32 *)&VICVectAddr0;
57 cntl=(u32 *)&VICVectCntl0;
59 for(cnt=0;cnt<INTERRUPT_MAX_VIC;cnt++) {
60 if((cntl[cnt]&0x1f)==src_number) {
61 *((volatile u32 *)(addr+cnt))=0;
62 *((volatile u32 *)(cntl+cnt))=0;
67 void interrupt_soft_enable(u8 src_number) {
69 VICSoftInt=(1<<src_number);
72 int interrupt_enable(u8 src_number,u8 mode,u8 prio,u32 callback_addr) {
77 addr=(u32 *)&VICVectAddr0;
78 cntl=(u32 *)&VICVectCntl0;
80 /* check whether this ir source is allready assigned */
81 if(VICIntEnable&(1<<src_number))
82 return INTERRUPT_USED;
84 /* prepare depending on mode */
86 case INTERRUPT_MODE_FIQ:
87 VICIntSelect|=(1<<src_number);
89 case INTERRUPT_MODE_VIRQ:
91 return INTERRUPT_PRIORITY_USED;
92 *((volatile u32 *)(addr+prio))=callback_addr;
93 *((volatile u32 *)(cntl+prio))=(src_number&0x1f)+0x20;
94 case INTERRUPT_MODE_IRQ:
100 VICIntEnable=(1<<src_number);
102 return INTERRUPT_SET;
105 int interrupt_change_callback(u8 src_number,u32 callback) {
110 cntl=(u32 *)&VICVectCntl0;
111 addr=(u32 *)&VICVectAddr0;
114 while(i<INTERRUPT_MAX_VIC) {
115 if((*cntl&0x1f)==src_number) {
117 return INTERRUPT_CALLBACK_CHANGED;
122 return INTERRUPT_SRC_NOT_USED;
125 void interrupt_ack(void) {
130 // specific interrupt handling
132 // external interrupts
133 void interrupt_ext_ir_config(u8 eint,u8 wakeup,u8 mode,u8 polarity) {
139 EXTWAKE=(EXTWAKE&0xf)|(1<<eint);
141 EXTMODE=(EXTMODE&0xf)|(mode<<eint);
142 EXTPOLAR=(EXTPOLAR&0xf)|(polarity<<eint);
145 void interrupt_ext_ir_set(u8 eint) {
153 // timer counter interrupts
154 void interrupt_tc_config(u8 tcnum,u8 mode,u8 cap,u32 psv) {
161 T0CTCR=mode|(cap<<2);
166 T1CTCR=mode|(cap<<2);
171 void interrupt_tc_match_config(u8 tcnum,u8 mnum,u32 val,u8 mode) {
182 T0MCR=(T0MCR&0x0fff)|(mode<<(3*mnum));
186 T1MCR=(T1MCR&0x0fff)|(mode<<(3*mnum));
193 void interrupt_tc_capt_config(u8 tcnum,u8 cnum,u8 mode) {
202 T0CCR=(T0CCR&0x0fff)|(mode<<(3*cnum));
204 T1CCR=(T1CCR&0x0fff)|(mode<<(3*cnum));
207 void interrupt_tc_ir_set(u8 tcnum,u8 tcmc) {
223 void interrupt_pwm_set_rate(u32 rate) {
228 void interrupt_pwm_match_config(u8 mnum,u8 op,u8 mode,u32 val1,u32 val2) {
232 *((volatile u32 *)(addr+mnum))=mval;
233 PWMMCR=(PWMMCR&0x1fffff)|(mode<<(op*3));
236 void interrupt_pwm_enable(u8 mode,u32 ps_val) {
242 void interrupt_pwm_ir_set(u8 pwm_channel) {
244 PWMIR=(pwm_channel&0x0f)|((pwm_channel&0x70)<<4);
249 * the actual exception handlers (as defined in startup.s)
253 void interrupt_handler_reset(void) {
256 // undefined instruction
257 void interrupt_handler_undef_instruction(void) {
260 // software interrupt
261 void interrupt_handler_soft_ir(void) {
263 if(interrupt.default_soft_callback)
264 interrupt.default_soft_callback();
268 void interrupt_handler_prefetch_abort(void) {
272 void interrupt_handler_data_abort(void) {
276 void interrupt_handler_fiq(void) {
278 if(interrupt.fiq_callback)
279 interrupt.fiq_callback();