📄 ks8695intrctl.c
字号:
/* ks8695IntrCtl.c - KS8695P interrupt controller driver *//*modification history--------------------9/15/2003 Ritter Yeh created */#include "vxWorks.h"#include "config.h"#include "intLib.h"IMPORT int ffsMsb (UINT32);#define KS8695P_INT_VEC_BASE (0x0)/* hardware access methods */#define KS8695P_INT_REG_READ(reg,result) \ ((result) = *(volatile UINT32 *)(reg))#define KS8695P_INT_REG_WRITE(reg,data) \ (*((volatile UINT32 *)(reg)) = (data))/* Convert level number to vector number */#define KS8695P_INT_LVL_VEC_MAP(level, vector) \ ((vector) = ((level) + KS8695P_INT_VEC_BASE))/* Convert pending register value, to a level number */#define KS8695P_INT_PEND_LVL_MAP(pendReg, level) \ ((level) = (pendReg))/* driver constants */#define KS8695P_INT_ALL_ENABLED 0xFF03FFFF#define KS8695P_INT_ALL_DISABLED 0/* Local data *//* Current interrupt level setting (ks8695pIntLvlChg). */LOCAL UINT32 ks8695pIntLvlCurrent = KS8695P_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 ks8695pIntLvlEnabled;/* forward declarations */STATUS ks8695pIntLvlVecChk (int*, int*);STATUS ks8695pIntLvlVecAck (int, int);int ks8695pIntLvlChg (int);STATUS ks8695pIntLvlEnable (int);STATUS ks8695pIntLvlDisable (int);/********************************************************************************* ks8695pIntDevInit - 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: OK */int ks8695pIntDevInit (void) { /* install the driver routines in the architecture hooks */ sysIntLvlVecChkRtn = ks8695pIntLvlVecChk; sysIntLvlVecAckRtn = ks8695pIntLvlVecAck; sysIntLvlChgRtn = ks8695pIntLvlChg; sysIntLvlEnableRtn = ks8695pIntLvlEnable; sysIntLvlDisableRtn = ks8695pIntLvlDisable; ks8695pIntLvlEnabled = 0; /* all sources disabled */ KS8695P_REG_WRITE (REG_INT_ENABLE, 0); return OK; }/********************************************************************************* ks8695pIntLvlVecChk - check for and return any pending interrupts*** RETURNS: OK or ERROR if no interrupt is pending.*/STATUS ks8695pIntLvlVecChk ( int* pLevel, /* ptr to receive old interrupt level */ int* pVector /* ptr to receive current interrupt vector */ ) { int newLevel; UINT32 isr; /* Read pending interrupt register and mask undefined bits */ KS8695P_REG_READ (REG_INT_MASK_STATUS, isr); isr &= KS8695P_INT_CSR_MASK; /* If no interrupt is pending, return ERROR */ if (isr == 0) return ERROR; /* find first bit set in ISR, starting from highest-numbered bit */ if (newLevel = ffsMsb (isr), newLevel == 0) return ERROR; --newLevel; /* ffsMsb returns numbers from 1, not 0 */ /* fetch, or compute the interrupt vector number */ KS8695P_INT_LVL_VEC_MAP (newLevel, *pVector); /* Disable interrupt */ KS8695P_REG_BIT_CLR (REG_INT_ENABLE,(1 << newLevel)); return OK; }/********************************************************************************* ks8695pIntLvlVecAck - acknowledge the current interrupt** Acknowledge the current interrupt cycle. The level and vector values are* those generated during the ks8695pIntLvlVecChk() 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 ks8695pIntLvlVecAck ( int level, /* old interrupt level to be restored */ int vector /* current interrupt vector, if needed */ ) { return OK; }/********************************************************************************* ks8695pIntLvlChg - 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 ks8695pIntLvlEnable() routine.*** RETURNS: Previous interrupt level.*/int ks8695pIntLvlChg ( int level /* new interrupt level */ ) { if (level >= 0 && level < KS8695P_INT_NUM_LEVELS) { ks8695pIntLvlCurrent = level; return level; } return ks8695pIntLvlCurrent; }/********************************************************************************* ks8695pIntLvlEnable - enable a single interrupt level** Enable a specific interrupt level. ** RETURNS: OK or ERROR if the specified level cannot be enabled.*/STATUS ks8695pIntLvlEnable ( int level /* level to be enabled */ ) { int key; if (level < 0 || level >= KS8695P_INT_NUM_LEVELS) return ERROR; /* set bit in enable mask */ key = intLock (); ks8695pIntLvlEnabled |= (1 << level); KS8695P_REG_WRITE (REG_INT_ENABLE, ks8695pIntLvlEnabled); intUnlock (key); return OK; }/********************************************************************************* ks8695pIntLvlDisable - disable a single interrupt level** Disable a specific interrupt level. ** RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.*/STATUS ks8695pIntLvlDisable ( int level /* level to be disabled */ ) { int key; if (level < 0 || level >= KS8695P_INT_NUM_LEVELS) return ERROR; /* clear bit in enable mask */ key = intLock (); ks8695pIntLvlEnabled &= ~(1 << level); KS8695P_REG_WRITE (REG_INT_ENABLE, ks8695pIntLvlEnabled); intUnlock (key); return OK; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -