📄 at91intrctl.c
字号:
AT91_INT_REG_WRITE (AT91C_AIC_DCR, AT91C_AIC_DCR_PROT);
#endif /* AT91_INT_USE_PROTECT_MODE */
return OK;
}
/*******************************************************************************
*
* at91IntLvlConfigure - configure polarity and type of interrupt
*
* This routine configures the polarity and type (edge or level) or an
* interrupt. It should be called after initialisation of the driver and
* must be called before enabling the level.
*
* The return value ERROR indicates that the parameters were invalid.
*
* RETURNS: OK or ERROR if parameters invalid.
*/
STATUS at91IntLvlConfigure
(
int level, /* level to configure */
int features /* edge/level/positive/negative */
)
{
UINT32 bits;
if (level < 0 || level >= AT91_INT_NUM_LEVELS)
return ERROR;
/*
* Configure type:
*
* Bits to be written to configuration register are:
* 00 = level sensitive, active low
* 01 = edge triggered, negative edge
* 10 = level sensitive, active high (external)
* 11 = edge triggered, positive edge (external)
*/
AT91_INT_REG_READ ((AT91_INT_CSR_MODE + (level * 4)), bits);
bits &= 7; /* read priority back */
bits |= ((UINT32) features & 3) << 5; /* set priority */
AT91_INT_REG_WRITE ((AT91_INT_CSR_MODE + (level * 4)), bits);
return OK;
}
/*******************************************************************************
*
* at91IntLvlVecChk - 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.
*
* This routine must be called with CPU interrupts disabled.
*
* 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 */
)
{
int newLevel = 0;
AT91_INT_REG_READ (AT91_INT_CSR_VECT, newLevel);
#ifdef AT91_INT_USE_PROTECT_MODE
AT91_INT_REG_WRITE (AT91_INT_CSR_VECT, newLevel);
#endif /* AT91_INT_USE_PROTECT_MODE */
/* If no interrupt is pending, return ERROR */
if (newLevel == 0)
{
/*
* If there is no interrupt pending, then the architecture code
* will not call the intLvlVecAck routine, leading to an
* imbalance in the interrupt controller hardware stack. So, we
* need to issue the End Of Interrupt command here. Depending
* upon how we have been called by the architecture code, this
* may or may not indicate that there has been a spurious
* interrupt.
*/
AT91_INT_REG_WRITE (AT91_INT_CSR_EOIC, 0); /* issue End-of-Int cmd */
return ERROR;
}
if (newLevel > AT91_INT_NUM_LEVELS)
{
AT91_INT_REG_WRITE (AT91_INT_CSR_EOIC, 0); /* issue End-of-Int cmd */
return ERROR;
}
/* map the interrupting device to an interrupt level number */
/* change to new interrupt level, returning previous level to caller */
*pLevel = newLevel;
/* fetch, or compute the interrupt vector number */
AT91_INT_LVL_VEC_MAP (newLevel, *pVector);
return OK;
}
/*******************************************************************************
*
* at91IntLvlVecAck - acknowledge the current interrupt
*
* Acknowledge the current interrupt cycle. The level and vector values are
* those generated during the at91IntLvlVecChk() routine for this interrupt
* cycle. The basic action is to reset the current interrupt and return
* the interrupt level to its previous setting.
*
* 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 */
)
{
/* acknowledge the current interrupt cycle */
AT91_INT_REG_WRITE (AT91_INT_CSR_EOIC, 0); /* Write of any value will do */
return OK;
}
/*******************************************************************************
*
* at91IntLvlChg - change the interrupt level value
*
* This routine implements the overall interrupt setting. All levels
* up to and including the specifed level are disabled. All levels above
* the specified level will be enabled, but only if they were specifically
* enabled by the templateLvlEnable() routine.
*
* The specific priority level AT91_INT_NUM_LEVELS is valid and represents
* all levels enabled.
*
* RETURNS: Previous interrupt level.
*/
int at91IntLvlChg
(
int level /* new interrupt level */
)
{
return 0;
}
/*******************************************************************************
*
* at91IntLvlEnable - 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 (level < 0 || level >= AT91_INT_NUM_LEVELS)
return ERROR;
/* set bit in enable mask */
if (level > 0)
AT91_INT_REG_WRITE (AT91_INT_CSR_ENB, (1 << level));
return OK;
}
/*******************************************************************************
*
* at91IntLvlDisable - 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 (level < 0 || level >= AT91_INT_NUM_LEVELS)
return ERROR;
/* clear bit in enable mask */
if (level > 0)
AT91_INT_REG_WRITE (AT91_INT_CSR_DIS, (1 << level));
return OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -