au1500int.c

来自「au1500开发的应用程序」· C语言 代码 · 共 649 行 · 第 1/2 页

C
649
字号
    /* configure according to flags */

    if (flags & INT_TYPE_LEVEL)
        ic->ic_cfg2set = (1 << bit); /* LEVEL */
    else
        ic->ic_cfg2clr = (1 << bit); /* EDGE */

    if (flags & INT_LOW_LEVEL)
        ic->ic_cfg1set = (1 << bit); /* LOW_LEVEL */
    else
        ic->ic_cfg1clr = (1 << bit); /* HIGH_LEVEL */

    if (flags & INT_HIGH_LEVEL)
        ic->ic_cfg0set = (1 << bit); /* FALLING_EDGE */
    else
        ic->ic_cfg0clr = (1 << bit); /* RISING_EDGE */

    if (flags & INT_REQUEST1)
        ic->ic_assignclr = (1 << bit); /* req1 */
    else
        ic->ic_assignset = (1 << bit); /* req0 */

    if (flags & INT_NOWAKEUP)
        ic->ic_wakeclr = (1 << bit); /* no wakeup from Idle */
    else
        ic->ic_wakeset = (1 << bit); /* wakeup from Idle */
    }

/***************************************************************************
 *
 * au1000IntInit - initialize the Interrupt Controllers
 *
 * NOTE:
 * - This routine should not be called directly by the user.
 * 
 * RETURNS: N/A
 */

LOCAL void au1000IntInit (void)
    {
    int i;

    /* Set all to known state */

    ic0->ic_cfg0clr = ~0;
    ic0->ic_cfg1clr = ~0;
    ic0->ic_cfg2clr = ~0;
    ic0->ic_srcset = ~0;
    ic0->ic_assignset = ~0;
    ic0->ic_wakeclr = ~0;
    ic0->ic_maskclr = ~0;
    ic0->ic_testbit = 0;
    ic0->ic_risingclr = ~0;
    ic0->ic_fallingclr = ~0;

    ic1->ic_cfg0clr = ~0;
    ic1->ic_cfg1clr = ~0;
    ic1->ic_cfg2clr = ~0;
    ic1->ic_srcset = ~0;
    ic1->ic_assignset = ~0;
    ic1->ic_wakeclr = ~0;
    ic1->ic_maskclr = ~0;
    ic1->ic_testbit = 0;
    ic1->ic_risingclr = ~0;
    ic1->ic_fallingclr = ~0;

    /* enable GPIO inputs */

    sys->sys_pininputen = 0;

    /*
     * Configure interrupt polarities according to peripheral/board needs
     */

    for (i = 0; i < sizeof(intTypes); ++i)
        {
        au1500IntTypeSet(i + INT_NUM_IC0, intTypes[i]);
        }
        
    sysWbFlush();
    }

/***************************************************************************
 *
 * au1000IntEnable - enable individual interrupt
 *
 * NOTE:
 * - This routine should not be called directly by the user.
 * 
 * RETURNS: N/A
 */

void au1000IntEnable (int vector)
    {
    AU1000_IC *ic;
    int bit;

    /* convert vector into IC and bit */

    VEC_TO_IC_BIT(vector);
    
    /* enable interrupt */

    ic->ic_maskset = (1 << bit);
    }

/***************************************************************************
 *
 * au1000IntDisable - disable individual interrupt
 *
 * NOTE:
 * - This routine should not be called directly by the user.
 * 
 * RETURNS: N/A
 */

void au1000IntDisable (int vector)
    {
    AU1000_IC *ic;
    int bit;

    /* convert vector into IC and bit */

    VEC_TO_IC_BIT(vector);
    
    /* disable interrupt */

    ic->ic_maskclr = (1 << bit);
    }

/**************************************************************************
 *
 * sysCtrl0Req0IntDemux - Demux interrupts
 *
 * This routine is automatically called when an external interrupt (INTN0) 
 * occurs. It returns a vector on resolving the interrupt.
 *
 * Prioritization of interrutps occurrs as an artifact of the sequence in
 * which bits are tested (31..0).
 *
 * RETURNS : Interrupt number
 */

LOCAL int sysCtrl0Req0IntDemux
(
    int arg
    )
    {
    UINT32 req = ic0->ic_req0int;
    int bit = 0;

    __asm(".set mips32\n clz %0,%1 \n .set mips2 " : "=r" (bit) : "r" (req));
    
    if (bit != 32)
        {
        bit = 31 -  bit;                 /* convert to bit pos */
        ic0->ic_fallingclr = (1 << bit); /* ack */
        ic0->ic_risingclr = (1 << bit);  /* ack */
        return INT_NUM_IC0 + bit;
        }
    
    /* shouldn't get here. Spurious interrupt */
    
    return IV_GPIO31_VEC + 1;    
    }

/**************************************************************************
 *
 * sysCtrl0Req1IntDemux - Demux interrupts
 *
 * This routine is automatically called when an external interrupt (INTN1) 
 * occurs. It returns a vector on resolving the interrupt.
 *
 * Prioritization of interrutps occurrs as an artifact of the sequence in
 * which bits are tested (31..0).
 *
 * RETURNS : Interrupt number
 */

LOCAL int sysCtrl0Req1IntDemux
(
    int arg
    )
    {
    UINT32 req = ic0->ic_req1int;
    int bit = 0;

    __asm(".set mips32\n clz %0,%1 \n .set mips2 " : "=r" (bit) : "r" (req));

    if (bit != 32)
	{
        bit = 31 - bit;                      /* convert to bit pos */
        ic0->ic_fallingclr = (1 << bit);     /* ack */
        ic0->ic_risingclr = (1 << bit);      /* ack */
        return INT_NUM_IC0 + bit;
	}

    /* shouldn't get here. Spurious interrupt */

    return IV_GPIO31_VEC + 1;
    }

/**************************************************************************
 *
 * sysCtrl1Req0IntDemux - Demux interrupts
 *
 * This routine is automatically called when an external interrupt (INTN2) 
 * occurs. It returns a vector on resolving the interrupt.
 *
 * Prioritization of interrutps occurrs as an artifact of the sequence in
 * which bits are tested (31..0).
 *
 * RETURNS : Interrupt number
 */

LOCAL int sysCtrl1Req0IntDemux
(
    int arg
    )
    {
    UINT32 req = ic1->ic_req0int;
    int bit = 0;

    __asm(".set mips32\n clz %0,%1 \n .set mips2 " : "=r" (bit) : "r" (req));
    
    if (bit != 32)
	{
        bit = 31 - bit;                      /* convert to bit pos */
        ic1->ic_fallingclr = (1 << bit);     /* ack */
        ic1->ic_risingclr = (1 << bit);      /* ack */
        return INT_NUM_IC1 + bit;
	}

    /* shouldn't get here. Spurious interrupt */

    return IV_GPIO31_VEC + 1;
    }

/**************************************************************************
 *
 * sysCtrl1Req1IntDemux - Demux interrupts
 *
 * This routine is automatically called when an external interrupt (INTN3) 
 * occurs. It returns a vector on resolving the interrupt.
 *
 * Prioritization of interrutps occurrs as an artifact of the sequence in
 * which bits are tested (31..0).
 *
 * RETURNS : Interrupt number
 */

LOCAL int sysCtrl1Req1IntDemux
(
    int arg
    )
    {
    UINT32 req = ic1->ic_req1int;
    int bit = 0;

    __asm(".set mips32\n clz %0,%1 \n .set mips2 " : "=r" (bit) : "r" (req));
    if (bit != 32)
	{
        bit = 31 - bit;                      /* convert to bit pos */
        ic1->ic_fallingclr = (1 << bit);     /* ack */
        ic1->ic_risingclr = (1 << bit);      /* ack */
        return INT_NUM_IC1 + bit;
	}

    /* shouldn't get here. Spurious interrupt */

    return IV_GPIO31_VEC + 1;
    }



/***************************************************************************
 *
 * sysAutoAck - acknowledge the au1000 interrupt condition 
 *
 * This routine acknowledges an au1000 interrupt for a specified interrupt
 * vector.
 *
 * NOTE:
 * - This routine must be provided on all au1000 board support packages.  Most
 *   interrupts are automatically acknowledged in the interrupt service routine.
 *
 * RETURNS: The result of the interrupt acknowledge cycle.
 */

int sysAutoAck
(
    int vecNum		/* vector num of interrupt that bugs us */
    )
    {
    int result = 0;

    switch (vecNum)
	{
        case IV_TIMER_VEC:
	    sysCompareSet (0);
	    break;
	case IV_SWTRAP0_VEC:		/* software trap 0 */
	    return(result = sysSw0Ack ());
	    break;
	case IV_SWTRAP1_VEC:		/* software trap 1 */
	    return(result = sysSw1Ack ());
	    break;
	case IV_FPA_UNIMP_VEC:		/* unimplemented FPA oper*/
	case IV_FPA_INV_VEC:		/* invalid FPA operation*/
	case IV_FPA_DIV0_VEC:		/* FPA div by zero */
	case IV_FPA_OVF_VEC:		/* FPA overflow exception */
	case IV_FPA_UFL_VEC:		/* FPA underflow exception */
	case IV_FPA_PREC_VEC:		/* FPA inexact operation */
	    return (result = sysFpaAck ());
	    break;
	default:
	    return (-1);
	    break;
	}
    return (result);
    }


⌨️ 快捷键说明

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