📄 s3c2410intrctl.c
字号:
* are serviced after all others in least-significant bit first priority.
*
* Note that in this priority system, intLevelSet(n) does not necessarily
* disable interrupt bit n and all lower-priority ones but uses
* s2410IntLvlPriMap to determine which interrupts should be masked e.g.
* if s2410IntLvlPriMap[] contains { 9, 4, 8, 5, -1 }, intLevelSet(0)
* disables all interrupt bits; intLevelSet(1) enables interrupt bit 9 but
* disables interrupts 4, 8, 5 and all others not listed; intLevelSet(3)
* enables interrupt bits 9, 4 and 8 but disables all others. This
* enabling of interrupts only occurs if the interrupt has been explicitly
* enabled via a call to s2410IntLvlEnable().
*
* If the list is empty (contains just a terminator) or s2410IntLvlPriMap
* is declared as an int pointer of value 0 (this is more efficient),
* interrupts are handled as least-significant bit is highest priority.
*
* If the symbol S2410_INT_USE_PROTECT_MODE is defined, then the Protect
* mode feature of the S2410 is used: the appropriate bit is set in the
* Special Functions register, and the Interrupt Vector register is
* written to when appropriate, allowing the Interrupt Vector register to
* be read by a debugger.
*
* The Spurious Vector feature is utilised by this driver and spurious
* interrupts will be detected, and reported to the architecture code
* calling this driver.
*
* The BSP will call this routine to initialize this driver in
* sysHwInit2(), after initializing the main interrupt library, usually
* intLibInit(). This routine sets up the interrupt controller device by
* masking off all individual interrupt sources and then setting the
* interrupt level to enable all interrupts.
*
* The return value ERROR indicates that the contents of
* s2410IntLvlPriMap (if used) were invalid.
*
* INTERNAL
* The s2410IntLvlPriMap list is a list of ints rather than bytes because
* it causes the current compiler to generate faster code.
*
* RETURNS: OK or ERROR if s2410IntLvlPriMap invalid.
*/
int s2410IntDevInit (void)
{
/* install the driver routines in the architecture hooks */
sysIntLvlVecChkRtn = s2410IntLvlVecChk;
sysIntLvlVecAckRtn = s2410IntLvlVecAck;
/*sysIntLvlChgRtn = s2410IntLvlChg; */
sysIntLvlEnableRtn = s2410IntLvlEnable;
sysIntLvlDisableRtn = s2410IntLvlDisable;
S2410IntLvlEnabled=0x0; /* all sources disabled */
S2410_INT_REG_WRITE(rINTMOD,S2410_INT_ALL_IRQ_MODE);
S2410_INT_REG_WRITE(rPRIORITY,0x0);
S2410_INT_REG_WRITE(rINTMSK,BIT_ALLMSK);
S2410_INT_REG_WRITE(rINTSUBMSK,BIT_SUB_ALLMSK);
S2410_INT_REG_WRITE(rSRCPND,BIT_ALLMSK);
S2410_INT_REG_WRITE(rSUBSRCPND, BIT_SUB_ALLMSK);
S2410_INT_REG_WRITE(rINTPND, rINTPND);
return OK;
}
/*******************************************************************************
*
* s2410IntLvlEnable - 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 to
* enable interrupts of this priority (as configured by s2410IntLvlPriMap,
* if appropriate). When not enabled, the interrupt is blocked
* regardless of the overall interrupt level setting.
*
* The interrupt level must have been configured by a call to
* s2410IntLvlConfigure() before it is enabled by a call to this routine.
*
* RETURNS: OK or ERROR if the specified level cannot be enabled.
*/
STATUS s2410IntLvlEnable
(
int level /* level to be enabled */
)
{
int key;
if (level < 0 ||level >= S2410_INT_NUM_LEVELS)
return ERROR;
/* set bit in enable mask */
key=intLock();
S2410IntLvlEnabled|=(1<<level);
intUnlock(key);
S2410_INT_REG_WRITE(rINTMSK, ((~S2410IntLvlEnabled) & BIT_ALLMSK));
return OK;
}
/*******************************************************************************
*
* s2410IntLvlDisable - 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 to enable interrupts of this priority (as configured by
* s2410IntLvlPriMap, if appropriate).
*
* RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.
*/
STATUS s2410IntLvlDisable
(
int level /* level to be disabled */
)
{
int key;
if (level < 0 ||level >= S2410_INT_NUM_LEVELS)
return ERROR;
/* set bit in enable mask */
key=intLock();
S2410IntLvlEnabled&=~((1<<level));
intUnlock(key);
switch(level)
{
case INT_LVL_ADC:
S2410_INT_REG_WRITE(rINTMSK, ((~S2410IntLvlEnabled) & BIT_ALLMSK));
S2410_INT_REG_WRITE(rINTSUBMSK,(rINTSUBMSK|(~0x1FF)));
break;
case INT_LVL_UART0:
S2410_INT_REG_WRITE(rINTMSK, ((~S2410IntLvlEnabled) & BIT_ALLMSK));
S2410_INT_REG_WRITE(rINTSUBMSK,(rINTSUBMSK|(~0x7F8)));
break;
case INT_LVL_UART1:
S2410_INT_REG_WRITE(rINTMSK, ((~S2410IntLvlEnabled) & BIT_ALLMSK));
S2410_INT_REG_WRITE(rINTSUBMSK,(rINTSUBMSK|(~0x7C7)));
break;
case INT_LVL_UART2:
S2410_INT_REG_WRITE(rINTMSK, ((~S2410IntLvlEnabled) & BIT_ALLMSK));
S2410_INT_REG_WRITE(rINTSUBMSK,( rINTSUBMSK |(~0x63F)));
break;
default:
S2410_INT_REG_WRITE(rINTMSK, ((~S2410IntLvlEnabled) & BIT_ALLMSK));
}
return OK;
}
/*******************************************************************************
*
* s2410IntLvlVecChk - 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 s2410IntLvlVecChk(int * pLevel ,int * pVector)
{
UINT32 isr;
/* Read pending interrupt register and mask undefined bits */
isr = rINTOFFSET;
if (rSRCPND == 0)
return ERROR;
*pVector =isr;
*pLevel =isr;
return OK;
}
/*end of the handler of interrupt,to clear pend bit in pend register*/
STATUS s2410IntLvlVecAck (int level,int vector)
{
UINT32 pend;
pend=rINTPND;
rSRCPND=pend;
rINTPND=pend;
return OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -