📄 hfrk_irq.c
字号:
#include "dbldr_spec.h"#include "lib.h"#include "hfrk.h"#include "2410addr.h"#include "hfrk_irq.h"#define INT_OFFSET_IRQ_EINT0 (0)#define INT_OFFSET_IRQ_EINT1 (1)#define INT_OFFSET_IRQ_EINT2 (2)#define INT_OFFSET_IRQ_EINT3 (3)#define INT_OFFSET_IRQ_EINT4_7 (4)#define INT_OFFSET_IRQ_EINT8_23 (5)#define INT_OFFSET_IRQ_RESERVED6 (6) /* for s3c2410 */#define INT_OFFSET_IRQ_CAM (6) /* for s3c2440 */#define INT_OFFSET_IRQ_BATT_FLT (7)#define INT_OFFSET_IRQ_TICK (8)#define INT_OFFSET_IRQ_WDT (9)#define INT_OFFSET_IRQ_TIMER0 (10)#define INT_OFFSET_IRQ_TIMER1 (11)#define INT_OFFSET_IRQ_TIMER2 (12)#define INT_OFFSET_IRQ_TIMER3 (13)#define INT_OFFSET_IRQ_TIMER4 (14)#define INT_OFFSET_IRQ_UART2 (15)#define INT_OFFSET_IRQ_LCD (16)#define INT_OFFSET_IRQ_DMA0 (17)#define INT_OFFSET_IRQ_DMA1 (18)#define INT_OFFSET_IRQ_DMA2 (19)#define INT_OFFSET_IRQ_DMA3 (20)#define INT_OFFSET_IRQ_SDI (21)#define INT_OFFSET_IRQ_SPI0 (22)#define INT_OFFSET_IRQ_UART1 (23)#define INT_OFFSET_IRQ_RESERVED24 (24)#define INT_OFFSET_IRQ_NFCON (25) /* for s3c2440 */#define INT_OFFSET_IRQ_USBD (25)#define INT_OFFSET_IRQ_USBH (26)#define INT_OFFSET_IRQ_IIC (27)#define INT_OFFSET_IRQ_UART0 (28)#define INT_OFFSET_IRQ_SPI1 (29)#define INT_OFFSET_IRQ_RTC (30)#define INT_OFFSET_IRQ_ADCPARENT (31)#define SUB_INT_MSK_IRQ_EINT4 (4)#define SUB_INT_MSK_IRQ_EINT5 (5)#define SUB_INT_MSK_IRQ_EINT6 (6)#define SUB_INT_MSK_IRQ_EINT7 (7)#define SUB_INT_MSK_IRQ_EINT8 (8)#define SUB_INT_MSK_IRQ_EINT9 (9)#define SUB_INT_MSK_IRQ_EINT10 (10)#define SUB_INT_MSK_IRQ_EINT11 (11)#define SUB_INT_MSK_IRQ_EINT12 (12)#define SUB_INT_MSK_IRQ_EINT13 (13)#define SUB_INT_MSK_IRQ_EINT14 (14)#define SUB_INT_MSK_IRQ_EINT15 (15)#define SUB_INT_MSK_IRQ_EINT16 (16)#define SUB_INT_MSK_IRQ_EINT17 (17)#define SUB_INT_MSK_IRQ_EINT18 (18)#define SUB_INT_MSK_IRQ_EINT19 (19)#define SUB_INT_MSK_IRQ_EINT20 (20)#define SUB_INT_MSK_IRQ_EINT21 (21)#define SUB_INT_MSK_IRQ_EINT22 (22)#define SUB_INT_MSK_IRQ_EINT23 (23)#ifdef __DBLDR_DEBUG__#define HFRK_IRQ_PRT0(x0) printf((x0))#define HFRK_IRQ_PRT1(x0, x1) printf((x0), (x1))#define HFRK_IRQ_PRT2(x0, x1, x2) printf((x0), (x1), (x2))#define HFRK_IRQ_PRT3(x0, x1, x2, x3) printf((x0), (x1), (x2), (x3)#define ASSERT(x) assert((x))#else /* !__DBLDR_DEBUG__ */#define HFRK_IRQ_PRT0(x0)#define HFRK_IRQ_PRT1(x0, x1)#define HFRK_IRQ_PRT2(x0, x1, x2)#define HFRK_IRQ_PRT3(x0, x1, x2, x3)#define ASSERT(x)#endif /* __DBLDR_DEBUG__ */static UINT32 _g_isr_func[NR_IRQS];static UINT32 _g_isr_param[NR_IRQS];static UINT32 _g_org_irq_msk = 0xFFFFFFFF;volatile void call_isr(void){ UINT32 int_pend = rINTPND; UINT32 bit = 0x01; UINT32 i = 0; while (bit) { if (int_pend & bit) { /* clear the corresponding bit in source pending register */ rSRCPND = bit; /* clear the corresponding bit in interrupt pending register */ rINTPND = bit; if ((INT_OFFSET_IRQ_EINT4_7 == i) || (INT_OFFSET_IRQ_EINT8_23 == i)) { UINT32 ext_int_pend = rEINTPEND; UINT32 j; for (j = 4; j < 24; j++) { if (ext_int_pend & (1 << j)) { rEINTPEND = (1 << j); if (_g_isr_func[IRQ_EINT4 + (j - 4)]) { void (*func)(void *); func = (void (*)(void *))_g_isr_func[IRQ_EINT4 + (j - 4)]; func((void *)_g_isr_param[IRQ_EINT4 + (j - 4)]); } } } } else { UINT32 isr_index; if (i < INT_OFFSET_IRQ_EINT4_7) { isr_index = i; } else if (i > INT_OFFSET_IRQ_EINT8_23) { isr_index = i + 18; /* 18 = (7 - 4) + (23 - 8) */ } else { /* impossible here */ isr_index = (UINT32)-1; ASSERT(0); } if (_g_isr_func[isr_index]) { void (*func)(void *); func = (void (*)(void *))_g_isr_func[isr_index]; func((void *)_g_isr_param[isr_index]); } } } bit = 0x01 << (++i); }}void hfrk_init_irq(void){ UINT32 i; for (i = 0; i < NR_IRQS; i++) { _g_isr_func[i] = 0; _g_isr_param[i] = 0; }}STATUS hfrk_request_irq(UINT32 irq_num, void (*isr)(void *), void *param){ if ((irq_num >= NR_IRQS) || (NULL == isr)) { HFRK_IRQ_PRT0("ERROR - invalid parameter(s) in hfrk_request_irq()\n"); return ERROR; } if (NULL != _g_isr_func[irq_num]) { HFRK_IRQ_PRT0("WARNING - isr overwritten in hfrk_request_irq()\n"); } _g_isr_func[irq_num] = (UINT32)isr; _g_isr_param[irq_num] = (UINT32)param; return OK;}STATUS hfrk_free_irq(UINT32 irq_num){ if (irq_num >= NR_IRQS) { HFRK_IRQ_PRT0("ERROR - invalid parameter(s) in hfrk_free_irq()\n"); return ERROR; } if (_g_isr_func[irq_num]) { _g_isr_func[irq_num] = 0; _g_isr_param[irq_num] = 0; } else { HFRK_IRQ_PRT0("WARNING - null isr encountered in hfrk_free_irq()\n"); } return OK;}STATUS hfrk_enable_irq(UINT32 irq_num){ if (irq_num >= NR_IRQS) { HFRK_IRQ_PRT0("ERROR - invalid parameter(s) in hfrk_enable_irq()\n"); return ERROR; } if (irq_num >= IRQ_EINT4 && irq_num <= IRQ_EINT23) { rEINTMASK &= ~(1 << (irq_num - IRQ_EINT4 + SUB_INT_MSK_IRQ_EINT4)); if (irq_num >= IRQ_EINT4 && irq_num <= IRQ_EINT7) { rINTMSK &= ~(1 << INT_OFFSET_IRQ_EINT4_7); } else { rINTMSK &= ~(1 << INT_OFFSET_IRQ_EINT8_23); } } else if (irq_num < IRQ_EINT4) { rINTMSK &= ~(1 << irq_num); } else /* irq_num > IRQ_EINT23 */ { rINTMSK &= ~(1 << (irq_num - IRQ_EINT23 - 1 + INT_OFFSET_IRQ_RESERVED6)); } return OK;}STATUS hfrk_disable_irq(UINT32 irq_num){ if (irq_num >= NR_IRQS) { HFRK_IRQ_PRT0("ERROR - invalid parameter(s) in hfrk_enable_irq()\n"); return ERROR; } if (irq_num >= IRQ_EINT4 && irq_num <= IRQ_EINT23) { rEINTMASK |= (1 << (irq_num - IRQ_EINT4 + SUB_INT_MSK_IRQ_EINT4)); if (irq_num >= IRQ_EINT4 && irq_num <= IRQ_EINT7) { rINTMSK |= (1 << INT_OFFSET_IRQ_EINT4_7); } else { rINTMSK |= (1 << INT_OFFSET_IRQ_EINT8_23); } } else if (irq_num < IRQ_EINT4) { rINTMSK |= (1 << irq_num); } else /* irq_num > IRQ_EINT23 */ { rINTMSK |= (1 << (irq_num - IRQ_EINT23 - 1 + INT_OFFSET_IRQ_RESERVED6)); } return OK;}STATUS hfrk_lock_irq(void){ if (0xFFFFFFFF != rINTMSK) { _g_org_irq_msk = rINTMSK; rINTMSK = 0xFFFFFFFF; } return OK;}STATUS hfrk_unlock_irq(void){ if (0xFFFFFFFF == rINTMSK) { rINTMSK = _g_org_irq_msk; } return OK;}#define IRQ_TYPE_LOW_LEVEL (0x0)#define IRQ_TYPE_HIGH_LEVEL (0x1)#define IRQ_TYPE_FALLING_EDGE (0x2)#define IRQ_TYPE_RISING_EDGE (0x4)#define IRQ_TYPE_BOTH_EDGE (0x6)STATUS hfrk_set_ext_irq_type(UINT32 irq_num, UINT32 irq_type){ VUINT32 *gp_con_reg; VUINT32 *ext_int_reg; VUINT32 gp_con_val; VUINT32 ext_int_val; UINT32 gp_con_offset; UINT32 ext_int_offset; if ((irq_num < IRQ_EINT0 || irq_num > IRQ_EINT23) || ((IRQ_TYPE_LOW_LEVEL != irq_type) && (IRQ_TYPE_HIGH_LEVEL != irq_type) && (IRQ_TYPE_FALLING_EDGE != irq_type) && (IRQ_TYPE_RISING_EDGE != irq_type) && (IRQ_TYPE_BOTH_EDGE != irq_type))) { HFRK_IRQ_PRT0("ERROR - invalid parameter(s) in hfrk_set_irq_type()\n"); return ERROR; } if ((irq_num >= IRQ_EINT0) || (irq_num <= IRQ_EINT7)) { gp_con_reg = &rGPFCON; gp_con_val = rGPFCON; gp_con_offset = irq_num - IRQ_EINT0; ext_int_reg = &rEXTINT0; ext_int_val = rEXTINT0; ext_int_offset = irq_num - IRQ_EINT0; } else if ((irq_num >= IRQ_EINT8) || (irq_num <= IRQ_EINT15)) { gp_con_reg = &rGPGCON; gp_con_val = rGPGCON; gp_con_offset = irq_num - IRQ_EINT8; ext_int_reg = &rEXTINT1; ext_int_val = rEXTINT1; ext_int_offset = irq_num - IRQ_EINT8; } else /* (irq_num >= IRQ_EINT16) || (irq_num <= IRQ_EINT23) */ { gp_con_reg = &rGPGCON; gp_con_val = rGPGCON; gp_con_offset = irq_num - IRQ_EINT8; ext_int_reg = &rEXTINT2; ext_int_val = rEXTINT2; ext_int_offset = irq_num - IRQ_EINT16; } gp_con_val &= ~(0x03 << gp_con_offset); gp_con_val |= (0x02 << gp_con_offset); ext_int_val &= ~(0x07 << ext_int_offset); ext_int_val |= (irq_type << ext_int_offset); *gp_con_reg = gp_con_val; *ext_int_reg = ext_int_val; return OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -