第5章附录 S3C2410中断源名称

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

表6-1 中断控制器支持的56个中断源

表6-2 SRCPND寄存器的定义

表5-3 INTMOD寄存器的定义续表

实例6-1

完成一个S3C2410芯片中断源的中断控制程序的编写,需要完成四部分内容。第一部分的实例在前面已经介绍。下面介绍后三部分内容的编程实例。例程中所用到的一些寄存器常量等在头文件reg2410.h和isr.h中定义,详见附录。这两个头文件必须包含在例程文件中。

#include "../inc/reg2410.h"

#include "../inc/isr.h"

例程中还需要用到下面的结构体。

/* 定义结构体*/

typedef struct{

Interrupt_func_t InterruptHandlers;

void* data;

int valid; //设置中断是否有效1=有效0=无效

mask_func_t mask;

mask_func_t unmask;

mask_func_t ack_irq;

}struct_InterruptFunc;

static struct_InterruptFunc InterruptFunc[NR_IRQS]={NULL,};

static void ack_irq(unsigned int irq)

{

rSRCPND = (1 << irq);

rINTPND = (1 << irq);

}

static void mask_irq(unsigned int irq)

{

rINTMSK |= (1 << irq);

}

static void unmask_irq(unsigned int irq)

{

rINTMSK &= ~(1 << irq);

}

(1)56个中断源中断向量设置

/* 56个中断源的中断向量设置函数*/

void ISR_IrqHandler(void)

{

unsigned int irq=GetISROffsetClr(); //得到中断源的中断号

irq=fixup_irq(irq); //计算子中断源的地址偏移

if(irq>=NR_IRQS)

return;

if(InterruptFunc[irq].InterruptHandlers==NULL){

InterruptFunc[irq].ack_irq(irq); //清中断未决位

return;

}

/* 调用中断服务程序*/

InterruptFunc[irq].InterruptHandlers(irq, InterruptFunc[irq].data);

InterruptFunc[irq].ack_irq(irq); //清中断未决位

}

上述程序中,GetISROffsetClr()、fixup_irq()是用来计算中断源号及子中断源地址偏移的函数。程序代码如下:

// GetISROffsetClr()函数

int GetISROffsetClr()

{

//计算中断的偏移地址,高位优先

int i,ispr=rI_ISPR,tmp=1<<(MAXHNDLRS-1);

for(i=MAXHNDLRS;i>0;i--){

if(ispr&tmp){

return i-1;

}

tmp>>=1;

}

return -1;

}

// fixup_irq()函数

static unsigned int fixup_irq(int irq) {

unsigned int ret;

unsigned long sub_mask, ext_mask;

switch (irq) {

case IRQ_UART0:

sub_mask = rSUBSRCPND & ~rINTSUBMSK;

ret = get_subIRQ(sub_mask, 0, 2, irq);

break;

case IRQ_UART1:

sub_mask = rSUBSRCPND & ~rINTSUBMSK;

ret = get_subIRQ(sub_mask, 3, 5, irq);

break;

case IRQ_UART2:

sub_mask = rSUBSRCPND & ~rINTSUBMSK;

ret = get_subIRQ(sub_mask, 6, 8, irq);

break;

case IRQ_ADCTC:

sub_mask = rSUBSRCPND & ~rINTSUBMSK;

ret = get_subIRQ(sub_mask, 9, 10, irq);

break;

case IRQ_EINT4_7:

ext_mask = rEINTPEND & ~rEINTMASK;

ret = get_extIRQ(ext_mask, 4, 7, irq);

break;

case IRQ_EINT8_23:

ext_mask = rEINTPEND & ~rEINTMASK;

ret = get_extIRQ(ext_mask, 8, 23, irq);

break;

default:

ret = irq;

}

return ret;

}

(2)中断控制初始化

中断控制器初始化程序主要完成具体中断源的中断模式、中断屏蔽位、子中断屏蔽位的设置。根据5.2.3中介绍的寄存器格式,选择对应该中断源的寄存器位是设置为1,还是设置为0。

void ISR_Init(void)

{

int irq;

/* 设置所有中断源为IRQ模式,并首先屏蔽所有中断源*/

rINTMOD = 0x0; //所有中断源为IRQ模式

rINTMSK = BIT_ALLMSK; // BIT_ALLMSK =0xffffffff

rINTSUBMSK = BIT_SUB_ALLMSK; // BIT_SUB_ALLMSK= 0x7ff

/* 初始化结构体中的成员*/

for (irq=0; irq < NORMAL_IRQ_OFFSET; irq++) {

InterruptFunc[irq].valid = 1;

InterruptFunc[irq].ack_irq = ack_irq;

InterruptFunc[irq].mask = mask_irq;

InterruptFunc[irq].unmask = unmask_irq;

}

InterruptFunc[IRQ_RESERVED6].valid = 0;

InterruptFunc[IRQ_RESERVED24].valid = 0;

InterruptFunc[IRQ_EINT4_7].valid = 0;

InterruptFunc[IRQ_EINT8_23].valid = 0;

InterruptFunc[IRQ_EINT0].valid = 0;

InterruptFunc[IRQ_EINT1].valid = 0;

InterruptFunc[IRQ_EINT2].valid = 0;

InterruptFunc[IRQ_EINT3].valid = 0;

相关文档
最新文档