📄 s3c44b0xintrctl.c
字号:
/* s3c44b0xIntrCtl.c - Samsung s3c44b0x interrupt controller driver *//* Copyright elf. */#include "copyright_wrs.h"/*modification history--------------------*//*DESCRIPTION*/#include "vxWorks.h"#include "config.h"#include "intLib.h"#include "s3c44b0x.h"#if !defined (S3C44B0X_INTPND) || \ !defined (S3C44B0X_INTMASK_VAL) || !defined (S3C44B0X_INTNUMLEVELS)# error missing S3C44B0X interrupt definitions#endif/* Local data *//* forward declarations */STATUS s3c44b0xIntLvlVecChk (int*, int*);STATUS s3c44b0xIntLvlEnable (int);STATUS s3c44b0xIntLvlDisable (int);/* : 中断确认 */STATUS s3c44b0xIntLvlAck (int level, int vector){ S3C44B0X_REG_WRITE32 (S3C44B0X_I_ISPC,(1 << vector)); return OK;}/********************************************************************************* s3c44b0xIntDevInit - 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 s3c44b0xIntDevInit (void) { /* install the driver routines in the architecture hooks */ sysIntLvlVecChkRtn = s3c44b0xIntLvlVecChk; sysIntLvlEnableRtn = s3c44b0xIntLvlEnable; sysIntLvlDisableRtn = s3c44b0xIntLvlDisable;/* sysIntLvlVecAckRtn = s3c44b0xIntLvlAck;*/ S3C44B0X_REG_WRITE32 (S3C44B0X_I_ISPC, S3C44B0X_INTMASK_VAL); /* clear all irq */ S3C44B0X_REG_WRITE32 (S3C44B0X_F_ISPC, S3C44B0X_INTMASK_VAL); S3C44B0X_REG_WRITE32 (S3C44B0X_INTMSK, (S3C44B0X_INTMASK_VAL & (~(1<<26)))); /* all interrupt service is masked */ S3C44B0X_REG_WRITE32 (S3C44B0X_INTCON, ((1<<2)|(0<<1)|(1<<0))); S3C44B0X_REG_WRITE32 (S3C44B0X_INTMOD, 0); /* all irq mode */ }/********************************************************************************* s3c44b0xIntLvlVecChk - 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 s3c44b0xIntLvlVecChk ( int* pLevel, /* ptr to receive old interrupt level */ int* pVector /* ptr to receive current interrupt vector */ ) { int newLevel; int intPendMask = (1<<(S3C44B0X_INTNUMLEVELS-1)); int count; UINT32 isr; /* Read pending interrupt register and mask undefined bits */ S3C44B0X_REG_READ32(S3C44B0X_I_ISPR, newLevel); if ((newLevel & S3C44B0X_INTMASK_VAL) == 0) return ERROR; /* * Step through the bits looking for a 1. This *will* terminate. * We could use ffsLsb() for this if we don't mind the function call * overhead */ for (count = 0, isr = (S3C44B0X_INTNUMLEVELS-1); count < S3C44B0X_INTNUMLEVELS; count++) { if (intPendMask & newLevel) break; isr--; intPendMask >>= 1; } *pVector = isr; /* Acknowledge the interrupt as given in s3c44b0x ARM7 sample code */ S3C44B0X_REG_WRITE32 (S3C44B0X_I_ISPC, (1 << isr)); return OK; }/********************************************************************************* s3c44b0xIntLvlEnable - 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 s3c44b0xIntLvlEnable ( int level /* level to be enabled */ ) { int key, mask; if (level < 0 || level >= S3C44B0X_INTNUMLEVELS) return ERROR; /* clear bit in mask register */ key = intLock (); S3C44B0X_REG_READ32(S3C44B0X_INTMSK, mask); mask = (mask & ~(1<<level)) & S3C44B0X_INTMASK_VAL; S3C44B0X_REG_WRITE32(S3C44B0X_INTMSK, mask); intUnlock (key); return OK; }/********************************************************************************* s3c44b0xIntLvlDisable - 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 s3c44b0xIntLvlDisable ( int level /* level to be disabled */ ) { int key, mask; if (level < 0 || level >= S3C44B0X_INTNUMLEVELS) return ERROR; /* set bit in mask register */ key = intLock (); S3C44B0X_REG_READ32(S3C44B0X_INTMSK, mask); mask = (mask | (1<<level)) & S3C44B0X_INTMASK_VAL; S3C44B0X_REG_WRITE32 (S3C44B0X_INTMSK, mask); intUnlock (key); return OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -