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

📄 s3c2510intr.c.bak

📁 s3c2510 VxWorks BSP包
💻 BAK
字号:
/* s3c2510Intr.c - SAMSUNG S3C2510 interrupt controller driver */

/* Copyright 2002 SAMSUNG ELECTRONICS */

/*
modification history
--------------------
01b,17July02,jwchoi
01a,08feb02,jmLee   created.
*/


#include "vxWorks.h"
#include "intLib.h"
#include "iv.h"

#include "drv/multi/s3c2510.h"
#include "config.h"
#include "drv/intrCtl/s3c2510Intr.h"


/*
 * Because FIQ is not handled within VxWorks, all interrupts should be processed
 * in IRQ mode.
*/

#define INTERNAL_INT_MODE               0x00000000          /* Internal Interrupt (Level 6 ~ 35) */
#define EXTERNAL_INT_MODE               0x00000000          /* External Interrupt (Level 0 ~ 5) */




#define DEBUG_LOG(x, p1, p2, p3, p4, p5, p6) \
        logMsg(x, (int)(UINT32)(p1), (int)(UINT32)(p2), (int)(UINT32)(p3), (int)(UINT32)(p4), (int)(UINT32)(p5), (int)(UINT32)(p6))



/* Interrupt priority table : Default value*/

LOCAL UINT32 intPriority[] = {
    0x03020100, /*                      Low  */
    0x07060504, /*                       .   */
    0x0B0A0908, /*                       .   */
    0x0F0E0D0C, /*                       .   */
    0x13121110, /*                       .   */
    0x17161514, /*                       .   */
    0x1B1A1918, /*                       .   */
    0x1F1E1D1C, /*                      High */
    0x23222120, /* High ........... Low      */    
};

/* Local forward declarations */

LOCAL STATUS s3c2510IntLvlVecChk(int *pLevel, int *pVector);
LOCAL STATUS s3c2510IntLvlVecAck(int level, int vector);
LOCAL STATUS s3c2510IntLvlEnable(int level);
LOCAL STATUS s3c2510IntLvlDisable(int level);


/*******************************************************************************
*
* s3c2510IntDevInit - 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 s3c2510IntrInit(void)
{
    /* Setup interrupt mode. */
    *S3C2510_INTINTMOD = INTERNAL_INT_MODE;
    *S3C2510_EXTINTMOD = EXTERNAL_INT_MODE;

    /* Disable all interrupts, but enable global interrupt. */
    *S3C2510_INTINTMASK = S3C2510_INT_MASK_INTERNAL;
    *S3C2510_EXTINTMASK = S3C2510_INT_MASK_EXTERNAL & ~S3C2510_INT_GLOBAL;
    
    printf(" Internal %x  External %x\n", *S3C2510_INTINTMASK, *S3C2510_EXTINTMASK);

    /* Setup interrupt priority. */
    *S3C2510_INTPRIOR0 = intPriority[0];
    *S3C2510_INTPRIOR1 = intPriority[1];
    *S3C2510_INTPRIOR2 = intPriority[2];
    *S3C2510_INTPRIOR3 = intPriority[3];
    *S3C2510_INTPRIOR4 = intPriority[4];
    *S3C2510_INTPRIOR5 = intPriority[5];
    *S3C2510_INTPRIOR6 = intPriority[6];
    *S3C2510_INTPRIOR7 = intPriority[7];
    *S3C2510_INTPRIOR8 = intPriority[8];
    

    /* Install the driver routines in the architecture hooks. */
    sysIntLvlVecChkRtn  = s3c2510IntLvlVecChk;
    sysIntLvlVecAckRtn	= s3c2510IntLvlVecAck;
    sysIntLvlEnableRtn  = s3c2510IntLvlEnable;
    sysIntLvlDisableRtn = s3c2510IntLvlDisable;
}

/*******************************************************************************
*
* s3c2510IntLvlVecChk - 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. The current interrupt should be masked.
*
* 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.
*/

LOCAL STATUS s3c2510IntLvlVecChk(
    int *pLevel,                                            /* pointer to receive current interrupt level */
    int *pVector                                            /* pointer to receive current interrupt vector */
    )
{
    int level;
    int *Reg;

    /* Read Interrupt Offset Register. */
    
    level = (int)*S3C2510_INTOFFSET_IRQ;
    	
    if (level >= S3C2510_INT_NUM_LEVELS)
    {
    	DEBUG_LOG("\n\n: jwchoi check it 0x%x >\n\n", level,0,0,0,0,0);
        return ERROR;
    }

    *pLevel  = level;
    *pVector = level;

    /* Disable current interrupt. */
    s3c2510IntLvlDisable(level);

    return OK;
}

/*******************************************************************************
*
* s3c2510IntLvlVecAck - acknowledge the current interrupt
*
* Acknowledge the current interrupt cycle. The level and vector values are those
* generated during the s3c2510IntLvlVecChk() routine for this interrupt cycle.
* The basic action is to unmask the current interrupt.
*
* RETURNS: OK or ERROR if a hardware fault is detected.
*/

LOCAL STATUS s3c2510IntLvlVecAck(
    int level,                                              /* current interrupt level to be restored */
    int vector                                              /* current interrupt vector, if needed */
    )
{
    /* Enable current interrupt. */
    s3c2510IntLvlEnable(level);

    return OK;
}

/*******************************************************************************
*
* s3c2510IntLvlEnable - 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.
*/

LOCAL STATUS s3c2510IntLvlEnable(
    int level                                               /* level to be enabled */
    )
{
    int lockKey;

    if ((level < 0) || (level >= S3C2510_INT_NUM_LEVELS))
    {
        return ERROR;
    }

    lockKey = intLock();

    if (level < 6)                                          /* external interrupt (level 0 ~ 5) */
    {
        *S3C2510_EXTINTMASK &= ~(1 << level);
    }
    else                                                    /* internal interrupt (level 6 ~ 35) */
    {
        *S3C2510_INTINTMASK &= ~(1 << (level - 6));
    }

    intUnlock(lockKey);

    return OK;
}

/*******************************************************************************
*
* s3c2510IntLvlDisable - 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.
*/

LOCAL STATUS s3c2510IntLvlDisable(
    int level                                               /* level to be disabled */
    )
{
    int lockKey;

    if ((level < 0) || (level >= S3C2510_INT_NUM_LEVELS))
    {
        return ERROR;
    }

    lockKey = intLock();

    if (level < 6)                                          /* external interrupt (level 0 ~ 5) */
    {
        *S3C2510_EXTINTMASK |= (1 << level);
    }
    else                                                    /* internal interrupt (level 6 ~ 35) */
    {
        *S3C2510_INTINTMASK |= (1 << (level - 6));
    }

    intUnlock(lockKey);

    return OK;
}

⌨️ 快捷键说明

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