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

📄 ambaintrctl.c

📁 ATMEL920T的BSP及ETH等已经设备驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	    /*	     * set index in level map: to disable this interrupt and all	     * lower-priority ones, select the level one less than this	     */	    ambaIntLvlMap[i] = level - 1;	    }	}    /* do the rest of the levels */    i = 0;		/* lowest-numbered interrupt bit */    for ( ; level <= AMBA_INT_NUM_LEVELS; ++level)	{	/* copy previous level's mask to this one's */	ambaIntLvlMask[level] = ambaIntLvlMask[level - 1];	/* try to find a bit that has not yet been set */	for ( ; ; ++i)	    {	    bit = 1 << i;	    if ((ambaIntLvlMask[level] & bit) == 0)		{		/* this bit not set so put it in the mask */		ambaIntLvlMask[level] |= bit;		/*		 * set index in level map: to disable this interrupt and all		 * lower-priority ones, select the level one less than this		 */		ambaIntLvlMap[i] = level - 1;		break;		}	    }	}#endif    /* install the driver routines in the architecture hooks */    sysIntLvlVecChkRtn	= ambaIntLvlVecChk;    sysIntLvlVecAckRtn	= ambaIntLvlVecAck;    sysIntLvlChgRtn		= ambaIntLvlChg;    sysIntLvlEnableRtn	= ambaIntLvlEnable;    sysIntLvlDisableRtn	= ambaIntLvlDisable;    ambaIntLvlEnabled = 0; 	/* all sources disabled */    ambaIntLvlChg (AMBA_INT_ALL_ENABLED); /* enable all levels */    return OK;    }/********************************************************************************* ambaIntLvlVecChk - 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  ambaIntLvlVecChk    (    int* pLevel,  /* ptr to receive old interrupt level */    int* pVector  /* ptr to receive current interrupt vector */    )    {    int newLevel;    UINT32 isr;#ifdef AMBA_INT_PRIORITY_MAP    UINT32 *priPtr;    int bitNum;#endif    /* Read pending interrupt register and mask undefined bits */    AMBA_INT_REG_READ (AMBA_INT_CSR_PEND, isr);#ifdef AMBA_INT_CSR_MASK    isr &= AMBA_INT_CSR_MASK;#endif    /* If no interrupt is pending, return ERROR */    if (isr == 0)	return ERROR;#ifdef AMBA_INT_PRIORITY_MAP    priPtr = (UINT32 *)ambaIntLvlPriMap;    if (priPtr == 0)	bitNum = -1;    else	{	/* service interrupts according to priority specifed in map */	while (bitNum = *priPtr++, bitNum != -1)	    {	    /* bitNum = interrupt bit from priority map */	    if (isr & (1 << bitNum))		{		break;		}	    }	}    /*     * if priority scan didn't find anything, look for any bit set,     * starting with the lowest-numbered bit     */    if (bitNum == -1)	bitNum = ffsLsb (isr) - 1; /* ffsLsb returns numbers from 1, not 0 */    /* if no interrupt is pending, return ERROR */    if (bitNum == -1)	return ERROR;    /* map the interrupting device to an interrupt level number */    newLevel = ambaIntLvlMap[bitNum];#else    /* find first bit set in ISR, starting from lowest-numbered bit */    if (newLevel = ffsLsb (isr), newLevel == 0)	return ERROR;    --newLevel;		/* ffsLsb returns numbers from 1, not 0 */    /* map the interrupting device to an interrupt level number */    AMBA_INT_PEND_LVL_MAP (newLevel, newLevel);#endif	/* ifdef AMBA_INT_PRIORITY_MAP */    /* change to new interrupt level, returning previous level to caller */    *pLevel = ambaIntLvlChg (newLevel);    /* fetch, or compute the interrupt vector number */#ifdef AMBA_INT_PRIORITY_MAP    AMBA_INT_LVL_VEC_MAP (bitNum, *pVector);#else    AMBA_INT_LVL_VEC_MAP (newLevel, *pVector);#endif    return OK;    }/********************************************************************************* ambaIntLvlVecAck - acknowledge the current interrupt** Acknowledge the current interrupt cycle.  The level and vector values are* those generated during the ambaIntLvlVecChk() 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  ambaIntLvlVecAck    (    int level,	/* old interrupt level to be restored */    int vector	/* current interrupt vector, if needed */    )    {    /* restore the previous interrupt level */    ambaIntLvlChg (level);    return OK;    }/********************************************************************************* ambaIntLvlChg - 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 ambaIntLvlEnable() routine.** The specific priority level AMBA_INT_NUM_LEVELS is valid and represents* all levels enabled.** RETURNS: Previous interrupt level.*/int  ambaIntLvlChg    (    int level	/* new interrupt level */    )    {    int oldLevel;    oldLevel = ambaIntLvlCurrent;    if (level >= 0 &&        level <= AMBA_INT_NUM_LEVELS)	{	/* change current interrupt level */	ambaIntLvlCurrent = level;	}    /* Switch off all interrupts */    AMBA_INT_REG_WRITE (AMBA_INT_CSR_DIS, -1);    /* Activate the enabled interrupts */    AMBA_INT_REG_WRITE (AMBA_INT_CSR_ENB,		(ambaIntLvlMask[ambaIntLvlCurrent] & ambaIntLvlEnabled));    return oldLevel;    }/********************************************************************************* ambaIntLvlEnable - 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 ambaIntLvlPriMap,* if appropriate).  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  ambaIntLvlEnable    (    int level  /* level to be enabled */    )    {    int key;    if (level < 0 ||	level >= AMBA_INT_NUM_LEVELS)	return ERROR;    /* set bit in enable mask */    key = intLock ();    ambaIntLvlEnabled |= (1 << level);    intUnlock (key);    ambaIntLvlChg (-1);	/* reset current mask */    return OK;    }/********************************************************************************* ambaIntLvlDisable - 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* ambaIntLvlPriMap, if appropriate).** RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.*/STATUS  ambaIntLvlDisable    (    int level  /* level to be disabled */    )    {    int key;    if (level < 0 ||	level >= AMBA_INT_NUM_LEVELS)	return ERROR;    /* clear bit in enable mask */    key = intLock ();    ambaIntLvlEnabled &= ~(1 << level);    intUnlock (key);    ambaIntLvlChg (-1);	/* reset current mask */    return OK;    }

⌨️ 快捷键说明

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