📄 irq.c
字号:
/*
* ApOS (Another Project software for s3c2410)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Copyright caiyuqing
*
*/
#include "../include/kernel/irq.h"
#include "../include/s3c2410/cpu.h"
#include "../include/s3c2410/s3c2410.h"
struct irq_ctrl_object irq_ctrl_object;
extern struct lcd_control_obj lcd_control_obj;
irq_ptr irq_rotunie[32]={
/* EINT0 */ (void *)0,
/* EINT1 */ (void *)0,
/* EINT2 */ (void *)0,
/* EINT3 */ (void *)0,
/* EINT4_7*/ (void *)0,
/* EINT8_23 */ (void *)0,
/* Reserved_1 */(void *)0,
/* nBATT_FLT*/ (void *)0,
/* INT_TICK */ (void *)0,
/* INT_WDT */ (void *)0,
/* INT_TIMER0 */(void *)0,
/* INT_TIMER1 */(void *)0,
/* INT_TIMER2 */(void *)0,
/* INT_TIMER3 */(void *)0,
/* INT_TIMER4 */(void *)0,
/* INT_UART2 */ (void *)0,
/* INT_LCD */ (void *)0,
/* INT_DMA0 */ (void *)0,
/* INT_DMA1 */ (void *)0,
/* INT_DMA2 */ (void *)0,
/* INT_DMA3 */ (void *)0,
/* INT_SDI */ (void *)0,
/* INT_SPI0 */ (void *)0,
/* INT_UART1 */ (void *)0,
/* Reserved_2 */(void *)0,
/* INT_USBD */ (void *)0,
/* INT_USBH */ (void *)0,
/* INT_IIC */ (void *)0,
/* INT_UART0 */ (void *)0,
/* INT_SPI1 */ (void *)0,
/* INT_RTC */ (void *)0,
/* INT_ADC */ (void *)0,
};
/*
* 开中断
*/
void irq_enable()
{
unsigned int cpsr_temp;
cpsr_temp=read_cpsr();
cpsr_temp&=~(1<<7);
write_cpsr(cpsr_temp);
}
/*
* 关中断
*/
void irq_disable()
{
unsigned int cpsr_temp;
cpsr_temp=read_cpsr();
cpsr_temp|=(1<<7);
write_cpsr(cpsr_temp);
}
/*
* 初始化 irq_ctrl_object 对象
*/
void irq_ctrl_obj_init(struct irq_ctrl_object *irqco)
{
irqco->src_pnd =&rSRCPND;
irqco->sub_src_pnd =&rSUBSRCPND;
irqco->int_mod =&rINTMOD;
irqco->int_msk =&rINTMSK;
irqco->sub_int_msk =&rINTSUBMSK;
irqco->priority =&rPRIORITY;
irqco->int_pnd =&rINTPND;
irqco->int_offset =&rINTOFFSET;
}
/*
* 中断组顺序选择
*/
int irq_arb_select(unsigned int arb_selX,unsigned int order)
{
unsigned int priority =*irq_ctrl_object.priority;
unsigned int tmp_order =0x00000003;
if(arb_selX>6)
return -1;
else
{
priority&=~(tmp_order<<arb_selX*2+7);
priority|=order<<arb_selX*2+7;
*irq_ctrl_object.priority=priority;
return 1;
}
}
/*
* 是否允许中断组顺序进行旋转变换
*/
int irq_rotate_enable(unsigned int arb_modX,unsigned int rotate_enable)
{
unsigned int priority =*irq_ctrl_object.priority;
unsigned int tmp_rotate_enable=0x00000001;
if(arb_modX>6)
return -1;
else
{
priority&=~(tmp_rotate_enable<<arb_modX);
priority|=rotate_enable<<arb_modX;
*irq_ctrl_object.priority=priority;
return 1;
}
}
/*
* 主中断屏蔽选择
*/
int irq_mask(unsigned int irq_X,unsigned int mask)
{
unsigned int int_msk =*irq_ctrl_object.int_msk;
unsigned int msk_tmp =0x00000001;
if(irq_X>31)
return -1;
else
{
int_msk&=~(msk_tmp<<irq_X);
int_msk|=mask<<irq_X;
*irq_ctrl_object.int_msk=int_msk;
return 1;
}
}
/*
* 从中断屏蔽选择
*/
int irq_sub_mask(unsigned int sub_irq_X,unsigned int sub_mask)
{
unsigned int sub_int_msk =*irq_ctrl_object.sub_int_msk;
unsigned int sub_msk_tmp =0x00000001;
if(sub_irq_X>10)
return -1;
else
{
sub_int_msk&=~(sub_msk_tmp<<sub_irq_X);
sub_int_msk|=sub_mask<<sub_irq_X;
*irq_ctrl_object.sub_int_msk=sub_int_msk;
return 1;
}
}
/*
* SRCPND寄存器相应位清0
*/
void clean_src_pnd(unsigned int sub_irqX)
{
*irq_ctrl_object.src_pnd=(1<<sub_irqX);
}
/*
* SUBSRCPND寄存器相应位清0
*/
void clean_sub_src_pnd(unsigned int sub_irqX)
{
*irq_ctrl_object.sub_src_pnd=(1<<sub_irqX);
}
/*
* INTPND寄存器相应位清0
*/
void clean_int_pnd(unsigned int sub_irqX)
{
*irq_ctrl_object.int_pnd=*irq_ctrl_object.int_pnd;
}
/*
* 中断处理函数,每当产生中断异常则do_irq被调用,do_irq通过
* *irq_ctrl_object.int_offset 对中断源进行识别并调用各个中
* 断源对应的中断服务例程。形参*regs是中断堆栈指针sp,该堆栈
* 中保存的是发生中断时UserMode的cpu现场(r0~r15,cpsr)
*/
void do_irq(struct cpu_registers *regs)
{
//各个设备的中断服务例程必须在初始化设备的时候被指定
irq_rotunie[*irq_ctrl_object.int_offset](regs);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -