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

📄 sngks32cintrctl.c

📁 基于4510的 (vxworks)BSP包 源代码
💻 C
字号:
/* sngks32cIntrCtl.c - Samsung KS32C interrupt controller driver *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01c,02oct01,m_h  race condition01b,26apr01,m_h  convert tabs to spaces for readability01a,12apr01,m_h  created from snds100 template.*//*DESCRIPTIONThis module implements interrupt controller driver for Samsung's KS32C50100microprocessor which is an ARM based processor with several integrated peripherals.  It has an interrupt controller, two 32-bit timers, one Ethernet controller, two HDLC controllers, one IIC controller, general purpose I/O ports, and a 2-channel DMA controller.The KS32C interrupt controller is a simple, generic interrupt controllerthat manages 21 levels of interrupts from various sources internal to themicroprocessor and external to it.  For external interrupts are supported.The interrupt controller has control and pending status registers, maskregister and supports level-sensitive interrupts.  This library providesthe routines to manage interrupts multiplexed by the KS32C interrupt controller.The KS32C interrupt controller registers used by this driver are describedbelow under the symbolic names used herein.SNGKS32C_INTENB (write): this is the mask register described in theKS32C50100 Users' Manual.  When this register is written, each data bit that is clear (0) causes the corresponding interrupt to be enabled.Each bit that is set (1) causes the corresponding interrupt to be disabled.SNGKS32C_INTPEND (read): this is the interrupt pending register.When this register is read, each data bit that is set (1) indicates thatan interrupt is pending from the corresponding source. Level 20 is thehighest priority and level 0 is the lowest.SNGKS32C_INTMODE (write): this register is used to configure the interruptsin FIQ or IRQ mode.  Each bit set in this register configures the correspondinginterrupt as FIQ.  Otherwise the interrupt is treated as IRQ.  VxWorksdoes not support the high priority FIQ mode of interrupts.  Hence all theinterrupts have to be configured in IRQ mode.The interrupt priority registers can be used to change the prioritiesof the interrupts from the default settings.  This feature is notsupported in this driver.  All the interrupts are set with the defaultpriority ordering.The number of interrupts supported by the device i.e. the number ofvalid bits in the SNGKS32C_INTPEND register (21), is specified bySNGKS32C_INTNUMLEVELS.sngks32carm7.h has defined the addresses of the controller chips registers:SNGKS32C_INTENB, SNGKS32C_INTDIS and SNGKS32C_INTPEND and also the driver constants SNGKS32C_INTMASK_VAL, SNGKS32C_INTNUMLEVELS.The chip registers are memory-mapped at specified addresses internal tothe processor.  32-bit accesses can be made to these register locations.The macros SNGKS32C_INT_REG_READ and SNGKS32C_INT_REG_WRITE are used toaccess these registers.The BSP will initialize this driver in sysHwInit2(), after initializingthe main interrupt library, usually intLibInit().  The initializationroutine, sngks32cIntDevInit() will setup the interrupt controller device,it will mask off all individual interrupt sources and then set theinterrupt level to enable all interrupts.  See sngks32cIntDevInit for moreinformation.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.SEE ALSO<Samsung KS32C50100 User's Manual>*/#include "vxWorks.h"#include "config.h"#include "intLib.h"#include "sngks32c.h"#if !defined (SNGKS32C_INTPEND) || !defined (SNGKS32C_INTENB) || \    !defined (SNGKS32C_INTMASK_VAL) || !defined (SNGKS32C_INTNUMLEVELS) || \    !defined (SNGKS32C_INTDIS)#   error missing SNGKS32C interrupt definitions#endif#define SNGKS32C_INT_VEC_BASE    (0x0)/* hardware access methods */#ifndef SNGKS32C_INT_REG_READ#   define SNGKS32C_INT_REG_READ(x,result) \        ((result) = *(volatile UINT32 *)(x))#endif    /*SNGKS32C_INT_REG_READ*/#ifndef SNGKS32C_INT_REG_WRITE#   define SNGKS32C_INT_REG_WRITE(x,data) \        (*((volatile UINT32 *)(x)) = (data))#endif /*SNGKS32C_INT_REG_WRITE*//* Convert level number to vector number */#ifndef SNGKS32C_INT_LVL_VEC_MAP#   define SNGKS32C_INT_LVL_VEC_MAP(level, vector) \        ((vector) = ((level) + SNGKS32C_INT_VEC_BASE))#endif/* Convert pending register value, to a level number */#ifndef SNGKS32C_INT_PEND_LVL_MAP#   define SNGKS32C_INT_PEND_LVL_MAP(pendReg, level) \        ((level) = (pendReg))#endif/* driver constants */#define SNGKS32C_INT_ALL_ENABLED     (SNGKS32C_INTNUMLEVELS)#define SNGKS32C_INT_ALL_DISABLED    (SNGKS32C_INTNUMLEVELS-1)/* Local data *//* * 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 sngks32cIntLvlEnabled;/* forward declarations */STATUS    sngks32cIntLvlVecChk  (int*, int*);STATUS    sngks32cIntLvlEnable  (int);STATUS    sngks32cIntLvlDisable (int);/********************************************************************************* sngks32cIntDevInit - 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 sngks32cIntDevInit (void)    {    /* install the driver routines in the architecture hooks */    sysIntLvlVecChkRtn     = sngks32cIntLvlVecChk;    sysIntLvlEnableRtn     = sngks32cIntLvlEnable;    sysIntLvlDisableRtn    = sngks32cIntLvlDisable;    sngks32cIntLvlEnabled  = 0x0;     /* all sources disabled */    SNGKS32C_INT_REG_WRITE (SNGKS32C_INTENB, ((~sngks32cIntLvlEnabled) & SNGKS32C_INTMASK_VAL));    SNGKS32C_INT_REG_WRITE (SNGKS32C_INTPEND, SNGKS32C_INTMASK_VAL);    SNGKS32C_INT_REG_WRITE (SNGKS32C_INTMODE,SNGKS32C_INTMODEIRQ);    }/********************************************************************************* sngks32cIntLvlVecChk - 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  sngks32cIntLvlVecChk    (    int* pLevel,  /* ptr to receive old interrupt level */    int* pVector  /* ptr to receive current interrupt vector */    )    {    int newLevel;    int intPendMask = 0x100000;    int count;    UINT32 isr;    /* Read pending interrupt register and mask undefined bits */    SNGKS32C_INT_REG_READ (SNGKS32C_INTPEND, newLevel);    if ((newLevel & SNGKS32C_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 = 20; count < SNGKS32C_INTNUMLEVELS; count++)        {        if (intPendMask & newLevel)            break;        isr--;        intPendMask >>= 1;        }    *pVector = isr;    /* Acknowledge the interrupt as given in SNGKS32C ARM7 sample code */    SNGKS32C_INT_REG_WRITE(SNGKS32C_INTPEND,(1 << isr));    return OK;    }/********************************************************************************* sngks32cIntLvlEnable - 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  sngks32cIntLvlEnable    (    int level  /* level to be enabled */    )    {    int key;    if (level < 0 ||        level >= SNGKS32C_INTNUMLEVELS)        return ERROR;    /* clear bit in mask register */    key = intLock ();    sngks32cIntLvlEnabled |= ((1 << level));    SNGKS32C_INT_REG_WRITE (SNGKS32C_INTENB, ((~sngks32cIntLvlEnabled) & SNGKS32C_INTMASK_VAL));    intUnlock (key);    return OK;    }/********************************************************************************* sngks32cIntLvlDisable - 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  sngks32cIntLvlDisable    (    int level  /* level to be disabled */    )    {    int key;    if (level < 0 ||        level >= SNGKS32C_INTNUMLEVELS)        return ERROR;    /* set bit in mask register */    key = intLock ();    sngks32cIntLvlEnabled &= ~(1 << level);    SNGKS32C_INT_REG_WRITE (SNGKS32C_INTENB, ((~sngks32cIntLvlEnabled) & SNGKS32C_INTMASK_VAL));    intUnlock (key);    return OK;    }

⌨️ 快捷键说明

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