* functions
*/
+// generaal interrupt handling
+
void interrupt_init(void) {
interrupt.default_soft_callback=0;
interrupt.default_soft_callback=callback;
}
+void interrupt_set_fiq_callback(void (*callback)(void)) {
+
+ interrupt.fiq_callback=callback;
+}
+
void interrupt_soft_clear(u8 src_number) {
VICSoftIntClr=(1<<src_number);
VICSoftInt=(1<<src_number);
}
-int interrupt_enable(u8 src_number,u8 mode,u8 priority,u32 callback_addr) {
+int interrupt_enable(u8 src_number,u8 mode,u8 prio,u32 callback_addr) {
u32 *addr;
u32 *cntl;
VICIntSelect|=(1<<src_number);
break;
case INTERRUPT_MODE_VIRQ:
- if(addr[priority]&0x3f)
+ if(addr[prio]&0x3f)
return INTERRUPT_PRIORITY_USED;
- *((volatile u32 *)(addr+priority))=callback_addr;
- *((volatile u32 *)(cntl+priority))=(src_number&0x1f)+0x20;
+ *((volatile u32 *)(addr+prio))=callback_addr;
+ *((volatile u32 *)(cntl+prio))=(src_number&0x1f)+0x20;
case INTERRUPT_MODE_IRQ:
default:
break;
return INTERRUPT_SRC_NOT_USED;
}
+void interrupt_ack(void) {
+
+ VICVectAddr=0;
+}
+
+// specific interrupt handling
+
+// external interrupts
void interrupt_ext_ir_config(u8 eint,u8 wakeup,u8 mode,u8 polarity) {
if(eint>3)
EXTINT=(1<<eint);
}
-void interrupt_ack(void) {
+// timer counter interrupts
+void interrupt_tc_config(u8 tcnum,u8 mode,u8 cap,u32 psc) {
- VICVectAddr=0;
+ if(tcnum>1)
+ return;
+
+ if(tcnum==0) {
+ T0TCR=0x03;
+ T0CTCR=mode|(cap<<2);
+ T0PR=psc;
+ }
+ else {
+ T1TCR=0x03;
+ T1CTCR=mode|(cap<<2);
+ T1PR=psc;
+ }
+}
+
+void interrupt_tc_match_config(u8 tcnum,u8 mnum,u32 val,u8 mode) {
+
+ u32 *mraddr;
+
+ if(tcnum>1)
+ return;
+
+ if(mnum>3)
+ return;
+
+ if(tcnum==0) {
+ T0MCR=mode<<(3*mnum);
+ mrddr=&T0MR0
+ }
+ else {
+ T1MCR=mode<<(3*mnum);
+ mrddr=&T1MR0
+ }
+
+ mraddr[mnum]=val;
+}
+
+void interrupt_tc_capt_config(u8 tcnum,u8 cnum,u8 mode) {
+
+ if(tcnum>1)
+ return;
+
+ if(cnum>3)
+ return;
+
+ if(tcnum==0)
+ T0CCR=mode<<(3*cnum);
+ else
+ T1CCR=mode<<(3*cnum);
+}
+
+void interrupt_tc_ir_set(u8 tcnum,u8 tcmc) {
+
+ if(tcnum>1)
+ return;
+
+ if(tcnum==0)
+ T0IR=tcmc;
+ else
+ T1IR=tcmc;
}
/*
// fiq
void interrupt_handler_fiq(void) {
+
+ if(interrupt.fiq_callback)
+ interrupt.fiq_callback();
}
#define INTERRUPT_EXT2 2
#define INTERRUPT_EXT3 3
+#define INTERRUPT_TC_MODE_T 0x00
+#define INTERRUPT_TC_MODE_CR 0x01
+#define INTERRUPT_TC_MODE_CF 0x02
+#define INTERRUPT_TC_MODE_CB 0x03
+
+#define INTERRUPT_TC_MATCH_IR 0x01
+#define INTERRUPT_TC_MATCH_RESET 0x02
+#define INTERRUPT_TC_MATCH_STOP 0x04
+
+#define INTERRUPT_TC_CAPT_R 0x01
+#define INTERRUPT_TC_CAPT_F 0x02
+#define INTERRUPT_TC_CAPT_I 0x04
+
+#define INTERRUPT_CAP0 0x00
+#define INTERRUPT_CAP1 0x01
+#define INTERRUPT_CAP2 0x02
+#define INTERRUPT_CAP3 0x03
+
+#define INTERRUPT_M0 0x01
+#define INTERRUPT_M1 0x02
+#define INTERRUPT_M2 0x04
+#define INTERRUPT_M3 0x08
+#define INTERRUPT_C0 0x10
+#define INTERRUPT_C1 0x20
+#define INTERRUPT_C2 0x40
+#define INTERRUPT_C3 0x80
+
#define INTERRUPT_SET 0x00
#define INTERRUPT_USED 0x01
#define INTERRUPT_PRIORITY_USED 0x02
typedef struct s_interrupt {
void (*default_soft_callback)(void);
+ void (*fiq_callback)(void);
} t_interrupt;
/* function prototypes */
void interrupt_init(void);
void interrupt_set_default_callback(u32 callback_addr);
void interrupt_set_soft_callback(void (*callback)(void));
+void interrupt_set_fiq_callback(void (*callback)(void));
void interrupt_soft_clear(u8 src_number);
void interrupt_clear(u8 src_number);
void interrupt_soft_enable(u8 src_number);
-int interrupt_enable(u8 src_number,u8 mode,u8 priority,u32 callback_addr);
+int interrupt_enable(u8 src_number,u8 mode,u8 prio,u32 callback_addr);
int interrupt_change_callback(u8 src_number,u32 callback_addr);
+
void interrupt_ext_ir_config(u8 eint,u8 wakeup,u8 mode,u8 polarity);
void interrupt_ext_ir_set(u8 eint);
void interrupt_ack(void);
+void interrupt_tc_config(u8 tcnum,u8 mode,u8 cap,u32 psc);
+void interrupt_tc_match_config(u8 tcnum,u8 mnum,u32 val,u8 mode);
+void interrupt_tc_capt_config(u8 tcnum,u8 cnum,u8 mode);
+void interrupt_tc_ir_set(u8 tcnum,u8 tcmc);
+
void interrupt_handler_reset(void);
void interrupt_handler_undef_instruction(void);
void interrupt_handler_soft_ir(void);