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

📄 int.c

📁 日本著名的的嵌入式实时操作系统T-Kernel的源码及用户手册。
💻 C
字号:
/* *---------------------------------------------------------------------- *    T-Kernel * *    Copyright (C) 2004 by Ken Sakamura. All rights reserved. *    T-Kernel is distributed under the T-License. *---------------------------------------------------------------------- * *    Version:   1.01.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2004/6/28. * *---------------------------------------------------------------------- *//* *	@(#)int.c (libtk/MC9328) * *	Interrupt controller operation *   *	Operation functions of interrupt controller support IRQ, GPIO, FPGA *	interrupts. Some functions treat part of those interrupts. *	FIQ interrupt is specified by IRQ interrupt vector which means the *	same factor. If invalid vector is specified, operation is not *	guaranteed. */#include <basic.h>#include <tk/syslib.h>#include <tk/sysdef.h>/* * Interrupt disable/enable */Inline UW _disint( void ){	UW	imask;	Asm("	mrs	%0, cpsr	\n"	"	orr	ip, %0, %1	\n"	"	msr	cpsr_c, ip	"		: "=r"(imask)		: "i"(PSR_DI)		: "ip" );	return imask;}Inline void _enaint( UW imask ){	Asm("msr cpsr_c, %0":: "r"(imask));}#define	_DI(imask)	( imask = _disint() )#define	_EI(imask)	( _enaint(imask) )/* * Set interrupt enable level *	Disable IRQ interrupts which level is less then or equal to specified *	'level'. 'level' must be '-1'-'15'. *	If '-1' is specified, all level IRQ interrupts are enable. *	If '15' is specified, all level IRQ interrupts are disable. *	'level' is set to the NIMASK register of interrupt controller. *	Initial value is '-1'. *	This function returns the interrupt enable level before being changed. */EXPORT INT SetIntLevel( INT level ){	INT	old;	old = in_w(NIMASK) & 0x1f;	if ( old == 0x1f ) old = -1;	out_w(NIMASK, level);	return old;}/* * Set interrupt mode *	Set accept mode to 'mode' regarding interrupt specified by 'intvec'. *	If 'mode' is not correct value, operation is not guaranteed. *    *	For IRQ,  mode := (IM_IRQ || IM_FIQ) *	Set the INTTYPE register of interrupt controller. *	Initial value is IM_IRQ. * *	For GPIO, mode := (IM_LEVEL || IM_EDGE) | (IM_HI || IM_LOW) *	Set the ICR register of GPIO controller. *   *	For FPGA interrupt, cannot set interrupt mode. */EXPORT void SetIntMode( INTVEC intvec, UINT mode ){	UW	msk, set;	INT	reg;	UW	imask;	if ( intvec < IV_GPA(0) ) {		/* IRQ */		intvec -= IV_IRQ(0);		reg = INTTYPEL - ((intvec >> 5) * 4);		msk = 1 << (intvec & 31);		set = ( (mode & IM_FIQ) != 0 )? msk: 0;		_DI(imask);		out_w(reg, (in_w(reg) & ~msk) | set);		_EI(imask);	} else {		/* GPIO */		intvec -= IV_GPA(0);		reg = ICR1_A + ((intvec >> 5) * 0x100);		reg += (intvec & 0x10) >> (4 - 2);		set = (intvec & 15) * 2;		msk = 3 << set;		set = (mode & 3) << set;		_DI(imask);		out_w(reg, (in_w(reg) & ~msk) | set);		_EI(imask);	}}/* * Enable interrupt *	Enable interrupt specified by 'intvec'. * *	For IRQ, level := '0'-'15'. *	level=0 means lowest priority level, level=15 means highest. *	If 'level' is outside this range, operation is not guaranteed. *	Set the NIPRIORITY register with the value 'level' and set *	interrupt enable to the INTENABLE register. *	For FIQ, 'level' has no mean. * *	For GPIO, 'level' is ignored. *	Set the IMR register of GPIO controller to interrupt enable. * *	For FPGA, 'level' is ignored. *	Set the IRQ_MASK register to interrupt enable. */EXPORT void EnableInt( INTVEC intvec, INT level ){	INT	reg, num;	UW	imask;	if ( intvec < IV_GPA(0) ) {		/* IRQ */		intvec -= IV_IRQ(0);		reg = NIPRIORITY0 - ((intvec >> 3) * 4);		num = (intvec & 7) * 4;		_DI(imask);		out_w(reg, (in_w(reg) & ~(15 << num)) | (level << num));		out_w(INTENNUM, intvec);		_EI(imask);	} else if ( intvec < IV_FPGA1(0) ) {		/* GPIO */		intvec -= IV_GPA(0);		reg = IMR_A + ((intvec >> 5) * 0x100);		num = intvec & 31;		_DI(imask);		out_w(reg, in_w(reg) | (1 << num));		_EI(imask);	} else {		/* FPGA */		intvec -= IV_FPGA1(0);		reg = ( intvec < 8 )? IRQ_MASK1: IRQ_MASK2;		num = intvec & 7;		_DI(imask);		out_b(reg, in_b(reg) | (1 << num));		_EI(imask);	}}/* * Disable interrupt *	Disable interrupt specified by 'intvec'. * *	For IRQ, set the INTENABLE register to interrupt disable state. * *	For GPIO, set the IMR register to interrupt disable. * *	For FPGA, set the IRQ_MASK register to interrupt disable. */EXPORT void DisableInt( INTVEC intvec ){	INT	reg, num;	UW	imask;	if ( intvec < IV_GPA(0) ) {		/* IRQ */		intvec -= IV_IRQ(0);		out_w(INTDISNUM, intvec);	} else if ( intvec < IV_FPGA1(0) ) {		/* GPIO */		intvec -= IV_GPA(0);		reg = IMR_A + ((intvec >> 5) * 0x100);		num = intvec & 31;		_DI(imask);		out_w(reg, in_w(reg) & ~(1 << num));		_EI(imask);	} else {		/* FPGA */		intvec -= IV_FPGA1(0);		reg = ( intvec < 8 )? IRQ_MASK1: IRQ_MASK2;		num = intvec & 7;		_DI(imask);		out_b(reg, in_b(reg) & ~(1 << num));		_EI(imask);	}}/* * Clear interrupt request *	Clear interrupt request specified by 'intvec'. *	This function is valid for GPIO and FPGA interrupts. *	For FPGA interrupt, clear 'GPIO Port A pin 7' which connected to FPGA. */EXPORT void ClearInt( INTVEC intvec ){	INT	reg;	if ( intvec >= IV_FPGA1(0) ) {		/* FPGA */		intvec -= IV_FPGA1(0);		reg = ( intvec < 8 )? IRQ_STR1: IRQ_STR2;		out_b(reg, ~(1 << (intvec & 7)));		intvec = IV_GPA(7);	}	/* GPIO */	intvec -= IV_GPA(0);	reg = ISR_A + ((intvec >> 5) * 0x100);	out_w(reg, 1 << (intvec & 31));}/* * Check interrupt request *	Check interrupt request specified by 'intvec'. *	If interrupt request occurs, returns TRUE (nonzero). */EXPORT BOOL CheckInt( INTVEC intvec ){	INT	reg;	if ( intvec < IV_FPGA1(0) ) {		if ( intvec < IV_GPA(0) ) {			/* IRQ */			intvec -= IV_IRQ(0);			reg = NIPNDL - ((intvec >> 5) * 4);		} else {			/* GPIO */			intvec -= IV_GPA(0);			reg = ISR_A + ((intvec >> 5) * 0x100);		}		return (in_w(reg) >> (intvec & 31)) & 1;	} else {		/* FPGA */		intvec -= IV_FPGA1(0);		reg = ( intvec < 8 )? IRQ_STR1: IRQ_STR2;		return (in_b(reg) >> (intvec & 7)) & 1;	}}

⌨️ 快捷键说明

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