📄 at91intrctl.c
字号:
/* AT91IntrCtl.c - AT91RM9200 AIC driver *//*modification history--------------------2004/10/25 this file is modified form VxWorks demo bsp integrator920t*//*DESCRIPTION*/#include "intLib.h"/* forward declarations */STATUS AT91IntLvlVecChk (int*, int*);/*STATUS AT91IntLvlVecAck (int, int);*/STATUS AT91IntLvlEnable (int);STATUS AT91IntLvlDisable (int);/********************************************************************************* sndsIntDevInit - initialize the interrupt controller** This routine will initialize the interrupt controller device, disabling all* interrupt sources. It will also 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*/void At91IntDevInit (void){ int i; AIC_S* paic = (AIC_S*)AIC_BASE_ADDR; /* dummy read result nIRQ, nFIQ to deassert state */ i = paic ->AIC_IVR; i = paic ->AIC_FVR; /* * setup the mode and vector for each interrupt * because we can not use the AIC automatic vector branch, we set * each vector to it's interrupt number, and we are easy to get interrupt number * when sndsIntLvlVecChk called. * set each interrupt mode to priority 0( lowest level ), edge trig mode */ for( i = 0; i<AIC_INT_NUM_LEVELS; i++ ) { paic ->AIC_SMR[i] = ( 7<<(AIC_SMR_PRIO_BIT) ); paic ->AIC_SVR[i] = (AT91_REG)(i|0x20000000); } /* SUPRISE INTERRUPT VECTOR, WE SET TO A LARGE VALUE */ paic ->AIC_SPU = (AIC_INT_NUM_LEVELS+10)|0x20000000; /* CURRENT WE USE PROTECT MODE, if used, IVR must be writed just after it readed */ paic ->AIC_DCR = 1; /* faster forceing, we do not use any interrupt routed to FIRQ */ paic ->AIC_FFER = 0; paic ->AIC_FFDR = 0xFFFFFFFE; /* leave last bit to 0, It's FIQ */ for( i = 0; i<8; i++ ) paic ->AIC_EOICR = 0; paic ->AIC_ICCR = 0xFFFFFFFF; /* install the driver routines in the architecture hooks */ sysIntLvlVecChkRtn = AT91IntLvlVecChk; sysIntLvlEnableRtn = AT91IntLvlEnable; sysIntLvlDisableRtn = AT91IntLvlDisable;/*
sysIntLvlVecAckRtn = AT91IntLvlVecAck;
*/
}/********************************************************************************* sndsIntLvlVecChk - 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 AT91IntLvlVecChk ( int* pLevel, /* ptr to receive old interrupt level */ int* pVector /* ptr to receive current interrupt vector */ ){ AIC_S* paic = (AIC_S*)AIC_BASE_ADDR; UINT32 newLevel; newLevel = paic ->AIC_IVR; paic ->AIC_IVR = newLevel; newLevel &= 0xFF; paic ->AIC_EOICR = 0xFFFFFFFF; if( newLevel >= AIC_INT_NUM_LEVELS ) return ERROR; newLevel &= (AIC_INT_NUM_LEVELS-1); *pVector = newLevel; return OK;}/********************************************************************************* sndsIntLvlEnable - 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 AT91IntLvlEnable ( int level /* level to be enabled */ ){ if ( ((UINT32)level) >= AIC_INT_NUM_LEVELS ) return ERROR; ((AIC_S*)AIC_BASE_ADDR)->AIC_IECR = (1 << level); return OK;}/********************************************************************************* sndsIntLvlDisable - 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 AT91IntLvlDisable ( int level /* level to be disabled */ ){ if ( ((UINT32)level) >= AIC_INT_NUM_LEVELS ) return ERROR; ((AIC_S*)AIC_BASE_ADDR)->AIC_IDCR = (1 << level);}/********************************************************************************* IntLvlVecAck - acknowledge the current interrupt** Acknowledge the current interrupt cycle. The level and vector values are* those generated during the IntLvlVecChk() routine for this interrupt* cycle. The basic action is to reset the current interrupt and return* the interrupt level to its previous setting. Note that the AMBA interrupt* controller does not need an acknowledge cycle.** RETURNS: OK or ERROR if a hardware fault is detected.* ARGSUSED*//*
STATUS AT91IntLvlVecAck
(
int level, / * old interrupt level to be restored * /
int vector / * current interrupt vector, if needed * /
)
{
/ *((AIC_S*)AIC_BASE_ADDR) ->AIC_EOICR = 0xFFFFFFFF;* / / * ack interrupt, int LEVEL stack adjuested * /
return OK;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -