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

📄 mpc107epic.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* mpc107Epic.c - Driver for Embedded Programmable Interrupt Controller *//* Copyright 1984-2000 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01b,11sep00,rcs fix include paths mpc107.h & mpc107Epic.h01a,18jun00,bri written*//*DESCRIPTIONThis module implements the Embedded Programmable Interrupt Controller (EPIC)driver for the MPC107 chip .The EPIC is an integrated interrupt controller in the MPC107 which providesthe following major capabilities:Support for five external interrupt sources or one serial-style interrupt(16 interrupt sources).Four global high-resolution timers that can be interrupt sources .Interrupt control for the MPC107 I2C unit, DMA unit (2 channels)and message unit (MU) .Processor initialization control : The processor can reset itself by settingthe processor initialization register, causing the assertion of the SRESETsignal .Programmable resetting of the EPIC unit through the global configurationregister16 programmable interrupt priority levelsFully nested interrupt deliverySpurious vector generation32 bit configuration registers that are aligned on 128 bit boundariesEPIC features are customized by writing into general control registers or intointerrupt level specific registers (IVPRs).This driver allows a basic interface to the EPIC such as intializing it,settinginterrupt vectors, priorities, level/edge sense and interrupt polarities, aswell as enabling and disabling specific interrupts.This driver implements a complete interrupt architecture system, complete withvector table.This driver provides the vector table for the system.  It can support a total of256 vectors.  In this driver the EPIC controller device can only generate 5different vectors, one for each external interrupt.If there are other devices in the system capable of generating their ownvectors then we presume that an appropriate interrupt handler is createdand attached to the vector associated with the correct IRQ number.  Thatinterrupt handler would get a new vector directly from the device and thencall all of the handlers attached to that new vector.  Vector information isstored in a linked list of INT_HANDLER_DESC structures. The sysIntTbl arraycontains a pointer to the first entry for each vector.This driver supports only "Direct IRQ" or "Serial IRQ" .It does not supportpass through mode ..SH INITIALIZATIONThis driver is initialized from the BSP, usually as part of sysHwInit().The first routine to be called is mpc107EpicInit(). The routine resets theglobal configuration register and resets the EPIC registers to defaultvalues.The user has to specify whether the interface is to be used for"Direct " or "Serial" IRQs .If "Serial" IRQ has to be used then the userhas to specify the  <clkRatio> .The second routine to be called is mpc107EpicIntrInit().  This routine takesno arguments. This routine allocates the vector table and initializes thechips to a default state.  All individual interrupt sources are disabled.Each has to be individually enabled by intEnable() before it will beunmasked and allowed to generate an interrupt..SH CUSTOMIZING THIS DRIVERThe macros CPU_INT_LOCK() and CPU_INT_UNLOCK provide the accessto the CPU level interrupt lock/unlock routines.  We presume that thereis a single interrupt line to the CPU.  By default these macros callintLock() and intUnlock() respectively.*//* includes */#include "vxWorks.h"#include "drv/multi/mpc107.h"#include "sysLib.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "drv/intrCtl/mpc107Epic.h"#include "excLib.h"#include "memLib.h"#include "intLib.h"#include "logLib.h"#ifdef INCLUDE_WINDVIEW#include "private/eventP.h"#endif/* defines */#ifndef CPU_INT_LOCK#   define CPU_INT_LOCK(pData) \	(*pData = intLock ())#endif#ifndef CPU_INT_UNLOCK#   define CPU_INT_UNLOCK(data) \	(intUnlock (data))#endif/* externs */IMPORT STATUS 	excIntConnect (VOIDFUNCPTR *, VOIDFUNCPTR);#if FALSE /* defined(INCLUDE_WINDVIEW) || defined(INCLUDE_INSTRUMENTATION) */IMPORT	int	evtTimeStamp;  /* Windview 1.0 only */#endif/* get the interrupt hook routines  prototypes*/IMPORT STATUS	(*_func_intConnectRtn) (VOIDFUNCPTR *, VOIDFUNCPTR, int);IMPORT int	(*_func_intEnableRtn) (int);IMPORT int	(*_func_intDisableRtn)  (int);/* globals */INT_HANDLER_DESC * sysIntTbl [INTERRUPT_TABLESIZE]; /* system interrupt tbl *//* locals *//* forward declarations */STATUS 		mpc107EpicIntConnect (VOIDFUNCPTR * vector, VOIDFUNCPTR routine,                                      int parameter);LOCAL STATUS	mpc107EpicIntEnable (int intNum);LOCAL STATUS	mpc107EpicIntDisable (int intNum);void 		mpc107EpicIntHandler (void);LOCAL ULONG 	mpc107EpicCurTaskPrioSet (int prioNum);LOCAL void 	mpc107EpicEOI(void);STATUS    	mpc107EpicTimerInit (void);VOID		mpc107EpicDelayTimer1 (UINT32 milliSec);int             mpc107EpicIntAck (void);STATUS          mpc107EpicIntSourceSet (ULONG srcAddr, int polarity, int sense,                                        int priority, int vector);int             mpc107EpicIntEnableVect (int srcAddr);int             mpc107EpicIntDisableVect (int srcAddr);STATUS          mpc107EpicsrcAddrCheck (ULONG srcAddr);/***************************************************************************** mpc107EpicInit - initialize the EPIC controller** This routine resets the global Configuration Register, thus it:* -  disables all interrupts* -  sets EPIC registers to reset values** It then sets the EPIC operation mode to Mixed Mode .** <irqType> is either Direct IRQs (0) or Serial Interrupt IRQs (1).* <clkRatio> is clock frequency driving the serial interrupt interface.** If <irqType> is Direct IRQs:* - <irqType> is written to the SIE bit of the EPIC Interrupt Configuration* register.* - <clkRatio> is ignored.** If <irqType> is Serial IRQs:* - both <irqType> and <clkRatio> will be written to the EPIC* Interrupt Configuration register.** RETURNS: N/A*/void mpc107EpicInit    (    ULONG 	irqType, 	/* irq type to initialize with */                                /* Direct IRQ or Serial IRQ    */    ULONG 	clkRatio	/* clock ratio  for Serial IRQ */    )    {    ULONG 	gcrVal;    ULONG 	icrVal;    int 	irq;    /* read Global Config Reg */    gcrVal = MPC107EUMBBARREAD (MPC107_EPIC_GLOBAL_REG);    gcrVal |= (MPC107_EPIC_GCR_RESET);    /* Reset the EPIC */    MPC107EUMBBARWRITE (MPC107_EPIC_GLOBAL_REG, gcrVal);    /* wait for the reset sequence to be completed */    while (MPC107EUMBBARREAD (MPC107_EPIC_GLOBAL_REG) & MPC107_EPIC_GCR_RESET)        {        ; /* do nothing */        }    /* configure for mixed mode */    gcrVal = MPC107EUMBBARREAD (MPC107_EPIC_GLOBAL_REG);    gcrVal |= (MPC107_EPIC_GCR_MODE_MIXED);    MPC107EUMBBARWRITE (MPC107_EPIC_GLOBAL_REG, gcrVal);    icrVal = MPC107EUMBBARREAD (MPC107_EPIC_INT_CONF_REG); /* read EICR */    if (irqType == MPC107_EPIC_DIRECT_IRQ)        {        icrVal &= ~(MPC107_EPIC_ICR_SEI); /* disable serial mode interrupts */        }    else /* serial mode is configured */        {        if (clkRatio != 0)            {            icrVal |= MPC107_EPIC_ICR_CLK_RATIO (clkRatio);            }        }    MPC107EUMBBARWRITE (MPC107_EPIC_INT_CONF_REG, icrVal);    while (mpc107EpicIntAck() != 0xff)      /* Clear all pending interrupts */        {        /* do nothing */	}    /* init all IVPRs to sense = 1, polarity = defined, vec = 0, prio = 0 */    for (irq = 0; irq < MPC107_EPIC_MAX_EXT_IRQS; irq++)        {        mpc107EpicIntDisable (MPC107_EPIC_VEC_REG(irq));        mpc107EpicIntSourceSet (MPC107_EPIC_VEC_REG(irq),                                MPC107_EPIC_INT_POLARITY,                                MPC107_EPIC_SENSE_LVL, 0x0, 0x0);        }    /* set it to highest priority */    mpc107EpicCurTaskPrioSet (MPC107_EPIC_PRIORITY_MAX);   /* Timer interface initialization */    mpc107EpicTimerInit ();    }/***************************************************************************** mpc107EpicIntrInit - initialize the interrupt table** This function initializes the interrupt mechanism of the board.** RETURNS: N/A*/VOID  mpc107EpicIntrInit (void)    {    int vector;    /* initialize the interrupt table */    for (vector = 0; vector < INTERRUPT_TABLESIZE; vector++)        {	sysIntTbl [vector] = NULL;        }    /*     * connect the interrupt demultiplexer to the PowerPC external     * interrupt exception vector.     * i. e.  put the address of this interrupt handler in     * the PowerPC's only external interrupt exception vector     * which is  _EXC_OFF_INTR = 0x500     */    excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, mpc107EpicIntHandler);    /*     * set up the BSP specific interrupt routines     * Attach the local routines to the VxWorks system calls     *     */    _func_intConnectRtn  =  mpc107EpicIntConnect;    _func_intEnableRtn   =  mpc107EpicIntEnable;    _func_intDisableRtn  =  mpc107EpicIntDisable;    /* set the task priority to the lowest priority */    mpc107EpicCurTaskPrioSet (MPC107_EPIC_PRIORITY_MIN);    }/***************************************************************************** mpc107EpicIntEnable - enable a EPIC interrupt** This routine enables a specified EPIC interrupt.** RETURNS: OK, or ERROR if the specified <intNum> is not correct .*/LOCAL int  mpc107EpicIntEnable    (    int intNum    )    {    if ((intNum < MPC107_EPIC_MAX_EXT_IRQS))        {	/* enable interrupt on EPIC */        mpc107EpicIntEnableVect (MPC107_EPIC_VEC_REG (intNum));        return OK;        }    else        return (ERROR);    }/***************************************************************************** mpc107EpicIntDisable - disable a EPIC interrupt level** This routine disables a specified EPIC interrupt level.** RETURNS: OK, or ERROR if the specified <intNum> is not correct .*/LOCAL int  mpc107EpicIntDisable    (    int 	intNum    )    {    if ((intNum < MPC107_EPIC_MAX_EXT_IRQS))        {        /* disable interrupt on EPIC */        mpc107EpicIntDisableVect (MPC107_EPIC_VEC_REG (intNum));        return OK;        }    else        return (ERROR);    }/***************************************************************************** mpc107EpicIntConnect - connect an interrupt handler to the system vector table** This function connects an interrupt handler to the system vector table.** RETURNS: OK, or ERROR if the <vector> is out of range or if memory* allocation has failed .*/STATUS mpc107EpicIntConnect    (    VOIDFUNCPTR * 	vector,		/* interrupt vector to attach */    VOIDFUNCPTR		routine,	/* routine to be called */    int			parameter	/* parameter to be passed to routine */    )    {    INT_HANDLER_DESC *	pNewHandler;    INT_HANDLER_DESC *	pCurrHandler;    int			intVal;    BOOL		sharing = FALSE;    if (((int)vector < 0)  || ((int) vector > INTERRUPT_TABLESIZE))	{        return (ERROR);   /*  out of range  */	}    /* create a new interrupt handler */    pNewHandler = (INT_HANDLER_DESC *)malloc (sizeof (INT_HANDLER_DESC));    /* check if the memory allocation succeed */    if (pNewHandler == NULL)	return (ERROR);    /*  initialize the new handler  */    pNewHandler->vec = routine;    pNewHandler->arg = parameter;    pNewHandler->next = NULL;    /* install the handler in the system interrupt table  */    intVal = intLock(); /* lock interrupts to prevent races */    if (sysIntTbl [(int) vector] == NULL)	{        sysIntTbl [(int) vector] = pNewHandler;  /* single int. handler case */	}    else	{        pCurrHandler = sysIntTbl[(int) vector];/* multiple int. handler case */        while (pCurrHandler->next != NULL)            {            pCurrHandler = pCurrHandler->next;            }        pCurrHandler->next = pNewHandler;        sharing = TRUE;	}        /* EPIC IRQ set EPIC registers  */        if (!sharing)            mpc107EpicIntSourceSet (MPC107_EPIC_VEC_REG((int)vector),                                    MPC107_EPIC_INT_POLARITY,                                    MPC107_EPIC_SENSE_LVL,                                    MPC107_EPIC_PRIORITY_GENERAL,                                    (int) vector);    intUnlock(intVal);    return (OK);    }/***************************************************************************** mpc107EpicIntDisconnect - disconnect an int. handler from the vector table** This function diconnects an interrupt handler from the system vector table.** RETURNS: OK, or ERROR if the <vector> is out of range or if the specified* <routine> is not found in the vector table .*/STATUS mpc107EpicIntDisconnect    (    VOIDFUNCPTR * 	vector,		/* interrupt vector to attach */    VOIDFUNCPTR		routine	/* routine to be called */    )    {    INT_HANDLER_DESC *	pCurrHandler;    INT_HANDLER_DESC *	pTempHandler;    int			intVal;    if (((int)vector < 0)  || ((int) vector > INTERRUPT_TABLESIZE))	{        return (ERROR);   /*  out of range  */	}    if (sysIntTbl [(int) vector] == NULL)	return (ERROR);    intLock (); /* lock interrupts to prevent races */    pCurrHandler = sysIntTbl[(int) vector];/* multiple int. handler case */    pTempHandler = pCurrHandler;    while (( pCurrHandler ->vec != routine) || (pCurrHandler == NULL))        {          pTempHandler = pCurrHandler;          pCurrHandler = pCurrHandler->next;        }     if (pCurrHandler != NULL)        {         if ((pCurrHandler ->vec == routine) && (pCurrHandler->next == NULL))            {            if (pTempHandler == pCurrHandler)                {                free (pCurrHandler);                sysIntTbl[(int) vector] = NULL;                }            else                {                pTempHandler->next =  pCurrHandler->next;                free (pCurrHandler);                }            }        }    intUnlock(intVal);    return (OK);    }/***************************************************************************** mpc107EpicIntHandlerExec  - execute the handlers for a given vector** This routine executes all the handlers chained to a given vector.

⌨️ 快捷键说明

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