S5pv210 cortex-a8 裸机gpio中断和eint中断

gpio中断:
一,启动时的操作
1.首先当然是操作cpsr寄存器来开启中断模式下的IRQ中断(因为在BL0中的程序将IRQ中断关闭了)
2.设置中断模式下的栈地址
3.中断前的环境保存和中断后的环境恢复
代码如下():
.global Reset
Reset:
	@关闭看门狗省略,bl0启动的时候已经关闭
	@msr cpsr_c,#0xd2       @进入中断模式 arm状态 禁止fiq irq
	@ldr sp,=0x22000000		 @栈指向sdram的地址
	
	@msr cpsr_c,#0xdf			@进入系统模式 arm状态 禁止fiq irq
	@ldr sp,=0x23000000		@栈指向sdram的地址
	ldr    sp, =0x40000000
	msr cpsr_c,#0x53		@0x5f	@系统模式下开irq中断
	
	bl init_irq
	
	ldr lr,=halt_loop @设置用于当前状态的返回地址
	@ldr sp,=0x24000000
	ldr pc,=main			@main里面为死循环闪灯
	
halt_loop:
	b halt_loop

.globl IRQ_Handle
IRQ_Handle:
	ldr sp, =0xD0037F80 @0xD0037F80 是中断向量表的栈底
	sub lr , lr , #4	@计算历史状态的返回地址
	stmdb sp! , {r0-r12,lr} @保存历史状态的寄存器值
	
	ldr lr,=int_return @设置用于当前状态的返回地址
	ldr pc,=EINT_Handle
	
int_return:
	ldmia sp! , { r0-r12,pc }^ @ ^表示将spsr的值复制到cpsr中去

二,gpio中断的初始化,即函数init_irq()
1.初始化中断向量表
2.中断跳转函数的定义,此处为EINT_Handle函数
3.GPIO中断的配置
代码如下:
void init_irq(void)
{
	//init EINT3
	
	Init_Vevtor();  //初始化中断向量表
	
	//清除中断使能(禁止中断)
		
    VIC0INTENCLEAR = 0xffffffff;
    VIC1INTENCLEAR = 0xffffffff;
    VIC2INTENCLEAR = 0xffffffff;
    VIC3INTENCLEAR = 0xffffffff;
    
    //设置所有中断源为IRQ中断
    VIC0INTSELECT = 0x0;
    VIC1INTSELECT = 0x0;
    VIC2INTSELECT = 0x0;
    VIC3INTSELECT = 0x0;

    //清除每个中断组服务程序入口地址,即四个VICxINTADDR寄存器
    *((unsigned long*)(0xF2000F00))=0; 
    *((unsigned long*)(0xF2100F00))=0;
    *((unsigned long*)(0xF2200F00))=0; 
    *((unsigned long*)(0xF2300F00))=0;

#if 0    //EINT中断配置
		GPH0CON|=(0XF<<12);							//选择EINT3中断功能
		EXT_INT_0_CON|=(0X2<<12);				//EINT3下降沿中断
		EXT_INT_0_MASK&=(~(1<<3));			//使能EINT中断
		VERCTOR_ADDR0(3)=EINT_Handle;  //中断处理函数
		EXT_INT_0_PEND|=(1<<3);				//清除中断标志    不知道为什么一开机中断标志就置位了
		VIC0INTENABLE|=(1<<3);					//中断向量表VIC0 EINT3使能
		//*((unsigned long*)(0xF200020C))=0; //设置优先级为0
#endif		

   GPD0CON|=(GPD0CON2); //INT FUNCTION 
    GPD0_INT_CON|=(GPD0_INT_CON2);//both edge triggered GD0_2,GD0_3
    GPD0_INT_MASK&=(~(1<<2));	
    VERCTOR_ADDR0(30)=EINT_Handle;   //set interrupt address
    //VERCTOR_PRIORITY0_30=0; //set priority 
    GPD0_INT_PEND|=(1<<2);
    VIC0INTENABLE = 1<<30;  //set  int enable
}

EINT外部中断只要把上述函数init_irq()中的外部中断的配置替换下就行了

代码链接:https://pan.baidu.com/s/1HV5uAAtVgl5vkcMsS5k83w

你可能感兴趣的:(linux)