⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irq.c

📁 ucosii下的arm9LCD程序
💻 C
字号:
/* * Copyright (C) 2002 MIZI Research, Inc. * * machine dependent irq handling routine * * Author: Nandy Lyu <nandy@mizi.com> * Date  : $Date: 2002/05/14 02:19:42 $  * * $Revision: 1.1.2.4 $   Tue May 21 2002 Nandy Lyu <nandy@mizi.com>   - initial   - BUG:	1) set_EINT_IRQ_edge 颊毫具 凳	2) INTSUBMSK绰 阿 device driver俊辑 力绢窍档废 秦具 窃.   Wed Aug 14 2002 Yong-iL Joh <tolkien@mizi.com>   - new irq scheme阑 利侩, 困俊 攫鞭等 bug 绊魔 * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file COPYING in the main directory of this archive * for more details. */#include "./hardware.h"#include "./irqs.h"#include "errno.h"#include "2410addr.h"#include "S3C2410.h"#define EINT_OFFSET(x)		((x) - NORMAL_IRQ_OFFSET + 4)#define SUBIRQ_OFFSET(x)	((x) - EXT_IRQ_OFFSET)#define EXTINT_MASK	0x7#if 1/* * set_GPIO_IRQ_edge - set interrupt signal for External Interrupts * * parameters: *	irq	number of external interrupt (IRQ_EINT0 ~ IRQ_EINT23) *	edge	signal method */#define EXTINT_OFFSET	0x4#define EXTINT_MASK	0x7int set_EXT_IRQ_mode(int irq, int edge) {	unsigned long flags;	int shift_value;	if (!(((IRQ_EINT4 <= irq) && (irq <= IRQ_EINT23)) ||	      ((IRQ_EINT0 <= irq) && (irq <= IRQ_EINT3))))	  return -EINVAL;	if (irq < IRQ_EINT4) {			/* IRQ_EINT0 ~ IRQ_EINT3 */	  shift_value = (irq % 8) * EXTINT_OFFSET;	  rEXTINT0 &= ~(EXTINT_MASK << shift_value);	  rEXTINT0 |= (edge << shift_value);	  ClearPending(0x1<<irq);	} else {	  shift_value = ((irq + 4) % 8) * EXTINT_OFFSET;	  if (irq < IRQ_EINT8) {		/* IRQ_EINT4 ~ IRQ_EINT7 */	    rEXTINT0 &= ~(EXTINT_MASK << shift_value);	    rEXTINT0 |= (edge << shift_value);	    rEINTPEND = (1 << shift_value);	    ClearPending(0x1<<IRQ_EINT4_7);	  } else if (irq < IRQ_EINT16) {	/* IRQ_EINT8 ~ IRQ_EINT15 */	    rEXTINT1 &= ~(EXTINT_MASK << shift_value);	    rEXTINT1 |= (edge << shift_value);	    rEINTPEND = (1 << shift_value);	    ClearPending(0x1<<IRQ_EINT8_23);	  } else {				/* IRQ_EINT16 ~ IRQ_EINT23 */	    rEXTINT2 &= ~(EXTINT_MASK << shift_value);	    rEXTINT2 |= (edge << shift_value);	    rEINTPEND = (1 << shift_value);	    ClearPending(0x1<<IRQ_EINT8_23);	  }	}		return 0;}#endif/* * External IRQ甫 力寇茄 IRQ甸阑 request_irq()肺 殿废窍扁 傈俊 * 购啊 秦林绢具 瞪 老甸捞 乐阑鳖夸? 力 积阿俊绰 绝促绊 壕聪促. * IRQ甸 吝俊辑 External IRQ(伙己俊辑 林厘窍绰 侩绢)父捞 GPIO甫 * 固府 汲沥窍绊 甸绢啊具 邓聪促. 弊贰辑 窍唱狼 窃荐俊辑 * 葛电 巴阑 秦搬秦 滚府绰 巴篮 绢冻鳖 酵焙夸. * * 2002.09.03 厘绕. */static int fixup_irq_num(int irq){	if (irq < IRQ_EINT4) return irq;	else return ((irq + 4) - NORMAL_IRQ_OFFSET);}static voidset_gpios(int irq, int pullup){	int shift;	if (irq < 8) {		shift = 2*irq;		rGPFCON &= ~(0x3 << shift);		rGPFCON |= (0x2 << shift);		rGPFUP &= ~(GRAB_PULLUP(pullup) << irq);		rGPFUP |= (GRAB_PULLUP(pullup) << irq);	} else {		shift = 2*(irq - 8);		rGPGCON &= ~(0x3 << shift);		rGPGCON |= (0x2 << shift);		rGPGUP &= ~(GRAB_PULLUP(pullup) << (irq - 8));		rGPGUP |= (GRAB_PULLUP(pullup) << (irq - 8));	} }int set_external_irq(int irq, int edge, int pullup){	unsigned long flags;	int real_irq, reg_ofs, shift;	volatile unsigned *extint = (volatile unsigned *)(0x56000088);	//printk(__FUNCTION__" called\n");	if (((irq < IRQ_EINT0) && (irq > IRQ_EINT23)) ||	    ((irq > IRQ_EINT3) && (irq < IRQ_EINT4)))		return -EINVAL;	real_irq = fixup_irq_num(irq);	//printk(__FUNCTION__"(): real_irq = %d\n", real_irq);	set_gpios(real_irq, pullup);	reg_ofs = (real_irq / 8);	//printk(__FUNCTION__"(): regs_ofs = %d\n", reg_ofs);	shift = 4 * (real_irq - 8 * reg_ofs);	extint += reg_ofs;	*extint &= ~(EXTINT_MASK << shift);	*extint |= (edge << shift);	if (irq < 4) {		rSRCPND |= (1 << real_irq);		rINTPND |= (1 << real_irq);	} else {		rEINTPEND |= (1 << real_irq);	}		return 0;}/* * Defined irq handlers */static void s3c2410_mask_ack_irq(unsigned int irq){	rINTMSK |= (1 << irq);	rSRCPND = (1 << irq);	rINTPND = (1 << irq);}static void s3c2410_mask_irq(unsigned int irq){	rINTMSK |= (1 << irq);}static void s3c2410_unmask_irq(unsigned int irq){	rINTMSK &= ~(1 << irq);}/* for EINT? */static void EINT4_23mask_ack_irq(unsigned int irq){	irq = EINT_OFFSET(irq);	rEINTMASK |= (1 << irq);	rEINTPEND = (1 << irq);	if (irq < EINT_OFFSET(IRQ_EINT8)) {//	  INTMSK |= (1 << SHIFT_EINT4_7);	  ClearPending(0x1<<SHIFT_EINT4_7);	} else {//	  INTMSK |= (1 << SHIFT_EINT8_23);	  ClearPending(0x1<<SHIFT_EINT8_23);	}}static void EINT4_23mask_irq(unsigned int irq){#if 0	if (irq < IRQ_EINT8) {	  INTMSK |= (1 << SHIFT_EINT4_7);	} else {	  INTMSK |= (1 << SHIFT_EINT8_23);	}#endif	irq = EINT_OFFSET(irq);	rEINTMASK |= (1 << irq);}static void EINT4_23unmask_irq(unsigned int irq){	rEINTMASK &= ~(1 << EINT_OFFSET(irq));	if (irq < IRQ_EINT8) {	  rINTMSK &= ~(1 << SHIFT_EINT4_7);	} else {	  rINTMSK &= ~(1 << SHIFT_EINT8_23);	}}/* for sub_IRQ */static void SUB_mask_ack_irq(unsigned int irq){	rINTSUBMSK |= (1 << SUBIRQ_OFFSET(irq));	rSUBSRCPND = (1 << SUBIRQ_OFFSET(irq));	if (irq <= IRQ_ERR0) {	  ClearPending(0x1<<SHIFT_UART0);        } else if (irq <= IRQ_ERR1) {	  ClearPending(0x1<<SHIFT_UART1);	} else if (irq <= IRQ_ERR2){	  ClearPending(0x1<<SHIFT_UART2);        } else {	/* if ( irq <= IRQ_ADC_DONE ) { */	  ClearPending(0x1<<SHIFT_ADCTC);	}}static void SUB_mask_irq(unsigned int irq){	rINTSUBMSK |= (1 << SUBIRQ_OFFSET(irq));}static void SUB_unmask_irq(unsigned int irq){	rINTSUBMSK &= ~(1 << SUBIRQ_OFFSET(irq));	if (irq <= IRQ_ERR0) {		rINTMSK &= ~(1 << SHIFT_UART0);         } else if (irq <= IRQ_ERR1) {		rINTMSK &= ~(1 << SHIFT_UART1);	} else if (irq <= IRQ_ERR2){	    	rINTMSK &= ~(1 << SHIFT_UART2);        } else {	/* if ( irq <= IRQ_ADC_DONE ) { */		rINTMSK &= ~(1 << SHIFT_ADCTC);        }}/* *  fixup_irq() for do_IRQ() in kernel/irq.c */ unsigned int get_subIRQ(int irq, int begin, int end, int fail_irq) {	int i;	for(i=begin; i <= end; i++) {	  if (irq & (1 << i))	    return (EXT_IRQ_OFFSET + i);	}	return fail_irq;} unsigned int get_extIRQ(int irq, int begin, int end, int fail_irq) {	int i;	for(i=begin; i <= end; i++) {	  if (irq & (1 << i))	    return (NORMAL_IRQ_OFFSET - 4 + i);	}	return fail_irq;}unsigned int fixup_irq(int irq) {    unsigned int ret;    unsigned long sub_mask, ext_mask;    if (irq == OS_TIMER)      return irq;    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;}void  s3c2410_init_irq(void) {    int irq;    /* disable all IRQs */    rINTMSK = 0xffffffff;    rINTSUBMSK = 0x7ff;    rEINTMASK = 0x00fffff0;    /* all IRQs are IRQ, not FIQ       0 : IRQ mode       1 : FIQ mode    */    rINTMOD = 0x00000000;    /* clear Source/Interrupt Pending Register */    rSRCPND = 0xffffffff;    rINTPND = 0xffffffff;    rSUBSRCPND = 0x7ff;    rEINTPEND = 0x00fffff0; }/* | $Id: event.c,v 1.1.2.4 2002/05/14 02:19:42 tolkien Exp $ | | Local Variables: | mode: c | mode: font-lock | version-control: t | delete-old-versions: t | End: | | -*- End-Of-File -*- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -