?? sysintrctl.c
字號(hào):
/* sysIntrCtl.c - template for interrupt controller driver *//* Copyright 2002, Wind River Systems, Inc. *//*TODO - Remove the template modification history and begin a new history starting with version 01a and growing the history upward with each revision.modification history--------------------01a,21may02,scm written.*//* TODO - Fill in this file with I/O addresses and related constants for the template BSP. Anything with "template" as a prefix needs to examined and re-named to id the BSP (i.e. iq80321, iq80310, etc.) *//*This module implements the template interrupt controller driver.The template does not have a true interrupt controller, so the interruptprocessing must be in non-preemptive mode. Effectively there is only oneinterrupt level, but there are 32 interrupt vectors. These are managedby the intArchLib.The number of interrupts supported by the software is template_INT_NUM_LEVELS.The actual registers referenced are: template_INTCTL_REG template_IINTSRC_REGWe assume that config.h or template.h has defined the above addresses.This driver assumes that the chip is memory-mapped and does directmemory accesses to the registers which are assumed to be 32 bits wide.If a different access method is needed, the BSP can redefine the macros.The BSP will initialize this driver in sysHwInit2(), after initializingthe main interrupt library, usually intLibInit(). The initializationroutine, templateIntDevInit() will setup the interrupt service.All of the functions in this library are global. This allows them tobe used by the BSP if it is necessary to create wrapper routines or toincorporate several drivers together as one.*/#include "vxWorks.h"#include "config.h"#include "intLib.h"/* TODO - for inclusion, define in config.h *//* show we're alive... */#ifdef INCLUDE_HEX_LED #define templateINT_HEART_BEAT#endif#ifdef templateINT_HEART_BEAT /* Watch Interrupts */LOCAL UINT32 IntMsb = L7SEG_Dot;LOCAL UINT32 IntLsb = L7SEG_ALL_OFF;LOCAL UINT32 IntCount = 0;#endif/* * This module implements the template interrupt controller driver.*//* * TODO - * flush out template defines in template.h, also * flush out low level routines in sysIntrCtl.s */IMPORT int ffsLsb (UINT32);IMPORT void sysINTCTL_MaskAll (void);IMPORT void sysINTSTR_SteerAll_Irq (void);IMPORT UINT32 sysIINTSRC_Read (void);IMPORT UINT32 sysINTCTL_Read (void);IMPORT void sysINTCTL_Write (UINT32 reg);/* hardware access methods *//* Convert level number to vector number */#ifndef template_INT_LVL_VEC_MAP#define template_INT_LVL_VEC_MAP(level, vector) \ ((vector) = ((level) + template_INT_VEC_BASE))#endif /* template_INT_LVL_VEC_MAP *//* Convert pending register value, to a level number */#ifndef template_INT_PEND_LVL_MAP#define template_INT_PEND_LVL_MAP(pendReg, level) \ ((level) = (pendReg))#endif /* template_INT_PEND_LVL_MAP *//* Local data *//* Current interrupt level setting (templateIntLvlChg). */LOCAL UINT32 templateIntLvlCurrent = 0; /* effectively have one level *//* forward declarations */STATUS templateIntLvlVecChk (int*, int*);STATUS templateIntLvlVecAck (int, int);int templateIntLvlChg (int);STATUS templateIntLvlEnable (int);STATUS templateIntLvlDisable (int);/********************************************************************************* templateIntDevInit - 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 or ERROR if templateIntLvlPriMap invalid.*/int templateIntDevInit (void) { int key; /* install the driver routines in the architecture hooks */ sysIntLvlVecChkRtn = templateIntLvlVecChk; sysIntLvlVecAckRtn = templateIntLvlVecAck; sysIntLvlChgRtn = templateIntLvlChg; sysIntLvlEnableRtn = templateIntLvlEnable; sysIntLvlDisableRtn = templateIntLvlDisable; /* Mask all the interrupts */ key = intLock (); sysINTCTL_MaskAll (); /* feed interrupts to template interrupt controller */ *((volatile UINT32 *)(template_PIRSR_REG)) = 0x0F; /* use IRQ lines only */ sysINTSTR_SteerAll_Irq (); intUnlock (key); return OK; }/********************************************************************************* templateIntLvlVecChk - 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 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 templateIntLvlVecChk ( int* pLevel, /* ptr to receive old interrupt level */ int* pVector /* ptr to receive current interrupt vector */ ) { UINT32 templateIntLvlEnabled; int newLevel; UINT32 isr; int key; /* Read pending interrupt register and mask undefined bits */ key = intLock (); isr = sysIINTSRC_Read (); templateIntLvlEnabled = sysINTCTL_Read (); intUnlock (key); isr = isr & template_RESERVED_INT_MSK; /* mask out reserved values */ isr &= templateIntLvlEnabled; /* exclude masked out interrupts */ /* If no interrupt is pending, return ERROR */ if (isr == 0) return ERROR;#ifdef templateINT_HEART_BEAT key = intLock (); *((volatile UINT8 *)(template_7SEG_LED_LSB_REG)) = IntLsb; *((volatile UINT8 *)(template_7SEG_LED_MSB_REG)) = IntMsb; intUnlock (key); if (IntMsb == L7SEG_ALL_OFF) { IntCount++; if(IntCount > 10) { IntMsb = L7SEG_Dot; IntLsb = L7SEG_ALL_OFF; IntCount = 0; } } else { IntCount++; if(IntCount > 10) { IntMsb = L7SEG_ALL_OFF; IntLsb = L7SEG_Dot; IntCount = 0; } }#endif /* find first bit set in ISR, starting from lowest-numbered bit */ if (newLevel = ffsLsb (isr), newLevel == 0) return ERROR; /* map the interrupting device to an interrupt level number */ --newLevel; /* ffsLsb returns numbers from 1, not 0 */ /* change to new interrupt level, effectively have one level */ *pLevel = templateIntLvlCurrent; /* fetch, or compute the interrupt vector number */ *pVector = newLevel; return OK; }/********************************************************************************* templateIntLvlVecAck - acknowledge the current interrupt** This is a no-op** Since templateIntLvlVecChk doesn't change the state of the system,* there is nothing here that needs to be undone.** It is assumed that the interrupt service routine has cleared the* interrupt source itself.** RETURNS: OK or ERROR if a hardware fault is detected.* ARGSUSED*/STATUS templateIntLvlVecAck ( int level, /* old interrupt level to be restored */ int vector /* current interrupt vector, if needed */ ) { return OK; }/********************************************************************************* templateIntLvlChg - change the interrupt level value** This is a no-op since we effectively have one level.** RETURNS: Previous interrupt level.*/int templateIntLvlChg ( int level /* new interrupt level */ ) { return templateIntLvlCurrent; }/********************************************************************************* templateIntLvlEnable - 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 templateIntLvlPriMap,* 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 templateIntLvlEnable ( int level /* level to be enabled */ ) { UINT32 templateIntLvlEnabled; int key; if (level < 0 || level >= template_INT_NUM_LEVELS) return ERROR; key = intLock (); /* Retrieve the unmasked interrupts */ templateIntLvlEnabled = sysINTCTL_Read (); /* set bit in enable mask */ templateIntLvlEnabled |= (1 << level); /* Activate the enabled interrupts */ sysINTCTL_Write (templateIntLvlEnabled); intUnlock (key); return OK; }/********************************************************************************* templateIntLvlDisable - 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* templateIntLvlPriMap, if appropriate).** RETURNS: OK or ERROR, if the specified interrupt level cannot be disabled.*/STATUS templateIntLvlDisable ( int level /* level to be disabled */ ) { UINT32 templateIntLvlEnabled; int key; if (level < 0 || level >= template_INT_NUM_LEVELS) return ERROR; key = intLock (); /* Retrieve the unmasked interrupts */ templateIntLvlEnabled = sysINTCTL_Read (); /* clear bit in enable mask */ templateIntLvlEnabled &= ~(1 << level); /* Activate the enabled interrupts */ sysINTCTL_Write (templateIntLvlEnabled); intUnlock (key); return OK; }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -