按键中断就是设置tiny6410上的GPIO,通过手册可知,需要设置寄存器
GPNCON跟GPLCON控制寄存器,
首先start.S修改中断初始化
init_stack:
msr cpsr_c, #0xd2
ldr sp, =0x53000000 //初始化r13_irq
msr cpsr_c, #0xd3
ldr sp, =0x54000000 //初始化r13_svc
mov pc, lr
/*初始化按键*/
#define GPNCON (volatile unsigned long*)0x7F008830
#define GPLCON (volatile unsigned long*)0x7F008814
void button_init()
{
*(GPNCON) = 0b10 | (0b10<<2);
*(GPLCON) = 0b0011<<16;
}
/*初始化中断*/
#define EINT0CON0 (volatile unsigned long*)0x7F008900
#define EINT0CON1 (volatile unsigned long*)0x7F008904
#define EINT0MASK (volatile unsigned long*)0x7F008920
#define VIC0INTENABLE (volatile unsigned long*)0x71200010
#define VIC1INTENABLE (volatile unsigned long*)0x71300010
#define VIC0VECTADDR (volatile unsigned long*)0x71200100
#define VIC1VECTADDR (volatile unsigned long*)0x71300104
#define ENIT0PEND (volatile unsigned long*)0x7F008924
#define VIC0ADDRESS (volatile unsigned long*)0x71200f00
#define VIC1ADDRESS (volatile unsigned long*)0x71300f00
//tiny6410特有的中断向量设置
void key1_isr()
{
//1保存环境
__asm__(
"sub lr, lr, #4\n"
"stmfd sp!, {r0-r12, lr}\n"
:
:
);
//2中断处理
led_on();
//3清除中断
*(ENIT0PEND) = ~0x0;
*(VIC0ADDRESS) = 0;
*(VIC1ADDRESS) = 0;
//4恢复环境
__asm__(
"ldmfd sp!, {r0-r12, pc}^ \n"
:
:
);
}
void key8_isr()
{
//1保存环境
__asm__(
"sub lr, lr, #4\n"
"stmfd sp!, {r0-r12, lr}\n"
:
:
);
//2中断处理
led_off();
//3清除中断
*(ENIT0PEND) = ~0x0;
*(VIC0ADDRESS) = 0;
*(VIC1ADDRESS) = 0;
//4恢复环境
__asm__(
"ldmfd sp!, {r0-r12, pc}^ \n"
:
:
);
}
void init_irq()
{
//配置按键中断发生的下降沿
*(EINT0CON0) = 0b010; //k1按键
*(EINT0CON1) = 0x010<<8;//k8按键
*(EINT0MASK) = 0; //取消屏蔽中断为了方便全部设置为零
//使能中断
*(VIC0INTENABLE) |= 0b1;
*(VIC1INTENABLE) |= 0b10;
*(VIC0VECTADDR) = (int)key1_isr;
*(VIC1VECTADDR) = (int)key8_isr;
//通过设置cpsr状态控制寄存器打开总的中断使能
//通过设置cp15寄存器来使能向量中断
__asm__(
"mrc p15,0,r0,c1,c0,0\n"
"orr r0, r0, #(1<<24)\n"
"mcr p15,0,r0,c1,c0,0\n"
"mrs r0, cpsr\n"
"bic r0, r0, #0x80\n"
"msr cpsr_c, r0\n"
:
:
);
}