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

📄 s3c2410xintrctl.c

📁 sumsung 公司arm9控制器S3c2410x的BSP.
💻 C
字号:
/* s3c2410xIntrCtl.c - s3c2410x interrupt controller driver */

/* Copyright 2004, HITSAT, Inc. */

#include "vxWorks.h"
#include "config.h"

IMPORT	FUNCPTR sysIntLvlVecChkRtn;
IMPORT	FUNCPTR sysIntLvlEnableRtn;
IMPORT	FUNCPTR sysIntLvlDisableRtn;

/* hardware access methods */
#ifndef s3c2410x_INT_REG_READ
#define s3c2410x_INT_REG_READ(reg,result) \
	((result) = *(volatile UINT32 *)(reg))
#endif

#ifndef s3c2410x_INT_REG_WRITE
#define s3c2410x_INT_REG_WRITE(reg,data) \
	(*((volatile UINT32 *)(reg)) = (data))
#endif



/* Local data 
#define s3c2410x_INT_ALL_ENABLED	(s3c2410x_INT_NUM_LEVELS)
#define s3c2410x_INT_ALL_DISABLED	(s3c2410x_INT_NUM_LEVELS-1)
*/

/* Current interrupt level setting (s3c2410xIntLvlChg). */
/*LOCAL UINT32 s3c2410xIntLvlCurrent = s3c2410x_INT_ALL_DISABLED;  all levels disabled */

/* 
 * A mask word.  Bits are set in this word when a specific level
 * is enabled. It is used to mask off individual levels that have
 * not been explicitly enabled.
 */
LOCAL UINT32 s3c2410xIntLvlEnabled;


/* forward declarations */
STATUS	s3c2410xIntLvlVecChk (int*, int*);
STATUS	s3c2410xIntLvlEnable (int);
STATUS	s3c2410xIntLvlDisable (int);

/*
 * s3c2410xIntDevInit - initialize the interrupt controller
 *
 * This routine will:
 *	<1> Initialize the interrupt controller device;
 *	<2> Disabling all interrupt sources;
 *	<3> Connect the device driver specific routines into the architecture level hooks.
 *
 *	If the BSP needs to create a wrapper routine around any of the arhitecture level routines,
 *	it should install the pointer to the wrapper routine after calling this routine.
 * 
 * RETURNS: N/A.
 */
int s3c2410xIntDevInit (void)
{
	UINT32 tempUINT32 = 0;
	
	/* <1> Initialize the interrupt controller device; */
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,0xfeffffbf);	/* Mask all Interrupt. */
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,0x7ff);	/* Mask all subInterrupt. */

	s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SUBSRCPND,tempUINT32);
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,tempUINT32);	/* Clear SUBSRCPND */
	
	s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SRCPND,tempUINT32);
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND,tempUINT32);	/* Clear SRCPND */
	
	s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTPND,tempUINT32);
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND,tempUINT32);	/* Clear INTPND. */
	
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMOD,0);		/* Select IRQ mode. */
	
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_PRIORITY,0);		/* Set priority. */
	
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_EINTSTYLE,EINT0_7_STYLE);
	
	/* <3> Install the driver routines in the architecture hooks */
	sysIntLvlVecChkRtn	= s3c2410xIntLvlVecChk;
	sysIntLvlEnableRtn	= s3c2410xIntLvlEnable;
	sysIntLvlDisableRtn	= s3c2410xIntLvlDisable;

	/* all sources disabled */
	s3c2410xIntLvlEnabled = 0;

	return OK;
}

/*
 * s3c2410xIntLvlVecChk - check for and return any pending interrupts
 *
 * This routine interrogates the hardware to determine the highest priority
 * interrupt pending.  It returns the vector associated with that interrupt, and
 * also the interrupt priority level prior to the interrupt (not the
 * level of the interrupt).  The current interrupt priority level is then
 * raised to the level of the current interrupt so that only higher priority
 * interrupts will be accepted until this interrupt is finished.
 *
 * The return value ERROR indicates that no pending interrupt was found and
 * that the level and vector values were not returned.
 *
 * RETURNS: OK or ERROR if no interrupt is pending.
 */
STATUS  s3c2410xIntLvlVecChk
	(
		int* pLevel,  /* ptr to receive old interrupt level */
		int* pVector  /* ptr to receive current interrupt vector */
	)
{
	UINT32 tempUINT32;
	
	/* Read pending interrupt register and mask undefined bits */
	s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTPND, tempUINT32);

	/* If no interrupt is pending, return ERROR */
	if((tempUINT32 & s3c2410x_INT_CSR_MASK_VAL) == 0) return ERROR;

	/* get the number of the pending interrupt */
	s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTOFFSET, tempUINT32);

	*pVector = tempUINT32;

	/* Ack interrupt for this level. */
	if((1<<tempUINT32)&((1<<INT_LVL_ADC)|(1<<INT_LVL_UART_0)|(1<<INT_LVL_UART_1)|(1<<INT_LVL_UART_2)))
	{
		s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK, 0x7ff);
	}
	/* s3c2410xIntLvlDisable(tempUINT32); */
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, (1<<tempUINT32));
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTPND, (1<<tempUINT32));

	return OK;
}


/*
 * s3c2410xIntLvlEnable - enable a single interrupt level
 *
 * Enable a specific interrupt level.  The enabled level will be allowed to
 * generate an interrupt, when the overall interrupt level is set below the
 * specified level.  Without being enabled, the interrupt is blocked regardless
 * of the overall interrupt level setting.
 *
 * RETURNS: OK or ERROR if the specified level cannot be enabled.
 */
STATUS  s3c2410xIntLvlEnable
	(
		int level  /* level to be enabled */
	)
{
	int key;
	
	if(level < 0 || level >= s3c2410x_INT_NUM_LEVELS) return ERROR;

	/* set bit in enable mask */
	key = intLock();
	s3c2410xIntLvlEnabled |= (1 << level);
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,	((~s3c2410xIntLvlEnabled) & s3c2410x_INT_CSR_MASK_VAL));
	intUnlock(key);

	return OK;
}

/*
 * s3c2410xIntLvlDisable - disable a single interrupt level
 *
 * Disable a specific interrupt level.  The disabled level is prevented
 * from generating an interrupt even if the overall interrupt level is set
 * below the specified level.
 *
 * RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.
 */
STATUS  s3c2410xIntLvlDisable
	(
		int level  /* level to be disabled */
	)
{
	int key;
	
	if(level < 0 || level >= s3c2410x_INT_NUM_LEVELS) return ERROR;

	/* clear bit in enable mask */
	key = intLock();
	s3c2410xIntLvlEnabled &= ~(1 << level);
	s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTMSK,	((~s3c2410xIntLvlEnabled) & s3c2410x_INT_CSR_MASK_VAL));
	intUnlock(key);

	return OK;
}









⌨️ 快捷键说明

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