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

📄 intr.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 2 页
字号:
    // Valid board-level interrupt?
    if (g_pBLRegs && (irq >= IRQ_MAINSTONEII_GPIO0_MIN) && (irq <= IRQ_MAINSTONEII_GPIO0_MAX))
    {
        UINT32 TempVal = (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);

        OUTREG32((PULONG)&g_pBLRegs->int_msk_en, (TempVal & ~FPGA_INT_BIT(irq)));

        // Masking the interrupt at the FPGA controller is enough - no need to mask the Bulverde GPIO0 interrupt.
        irq = OAL_INTR_IRQ_UNDEFINED;
    }

#if !WM_MAINSTONEII_FPGA_PEN_DETECT
    /*
     * Disable the pen detect interrupt.
     */
	if ( g_pGPIORegs && ( IRQ_GPIOXX_2_PEN_DETECT == irq ) )
	{
		g_pGPIORegs->PEN_DETECT_GPIO_REG(GRER) &= ~GPIO_BIT(PEN_DETECT_GPIO_NUM);
	}
#endif


    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrDisableIrq(irq = %d\r\n", irq));
    return irq;
}

//------------------------------------------------------------------------------
//
//  Function:  BSPIntrDoneIrq
//
//  This function is called from OALIntrDoneIrq to finish interrupt on
//  secondary interrupt controller or GPIO controller.
//
UINT32 BSPIntrDoneIrq(UINT32 irq)
{

    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+BSPIntrDoneIrq(%d)\r\n", irq));

    // Valid board-level interrupt?
    if (g_pBLRegs && (irq >= IRQ_MAINSTONEII_GPIO0_MIN) && (irq <= IRQ_MAINSTONEII_GPIO0_MAX))
    {
        UINT32 TempVal;

        TempVal = INREG32((PULONG)&g_pBLRegs->int_set_clr) & ~INTSETCLR_RESERVED_BITS;
        OUTREG32((PULONG)&g_pBLRegs->int_set_clr, (TempVal & ~FPGA_INT_BIT(irq)));

        TempVal = (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);
        OUTREG32((PULONG)&g_pBLRegs->int_msk_en, (TempVal | FPGA_INT_BIT(irq)));

        // Masking the interrupt at the FPGA controller is enough - no need to mask the Bulverde GPIO0 interrupt.
        irq = OAL_INTR_IRQ_UNDEFINED;
    }

#if !WM_MAINSTONEII_FPGA_PEN_DETECT
    /*
     * Enable the pen detect interrupt.
     */
	if ( g_pGPIORegs && ( IRQ_GPIOXX_2_PEN_DETECT == irq ) )
	{
		g_pGPIORegs->PEN_DETECT_GPIO_REG(GRER) |= GPIO_BIT(PEN_DETECT_GPIO_NUM);
	}
#endif

    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrDoneIrq(irq = %d)\r\n", irq));
    return irq;
}


//------------------------------------------------------------------------------
//
//  Function:  BSPIntrActiveIrq
//
//  This function is called from interrupt handler to give BSP chance to 
//  translate IRQ in case of secondary interrupt controller.
//
UINT32 BSPIntrActiveIrq(UINT32 irq)
{
    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+BSPIntrActiveIrq(%d)\r\n", irq));

    switch(irq)
    {
    case IRQ_GPIO0:
        irq = FPGAInterruptHandler(irq);
        break;

    case IRQ_GPIO1:
		break;

    case IRQ_GPIOXX_2:
        irq = GPIOInterruptHandler(irq);
		break;

    default:
        break;
    }

    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-BSPIntrActiveIrq(%d)\r\n", irq));
    return irq;
}


//------------------------------------------------------------------------------
//
//  Function:  FPGAInterruptHandler
//
//  This function is called from the BSP ISR to handle an FPGA interrupt.
//
static UINT32 FPGAInterruptHandler(UINT32 irq)
{
    UINT8  nInt;
    UINT32 TempVal;

    // Read the pending FPGA interrupts and ignore masked/reserved interrupts.
    TempVal  = INREG32((PULONG)&g_pBLRegs->int_set_clr);
    TempVal &= (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);

    // Scan through the pending interrupts and look for a match.
    for (nInt = IRQ_MAINSTONEII_GPIO0_MIN ; nInt <= IRQ_MAINSTONEII_GPIO0_MAX ; nInt++)
    {
        if (TempVal & FPGA_INT_BIT(nInt))
        {	
            // Mask and clear the interrupt (note that we must write 0's to the reserved bits).
            // Interrupt acknowledge occurs in the SMC ISR routine
            TempVal = INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS;
            OUTREG32((PULONG)&g_pBLRegs->int_msk_en,  (TempVal & ~FPGA_INT_BIT(nInt)));

            TempVal = INREG32((PULONG)&g_pBLRegs->int_set_clr) & ~INTSETCLR_RESERVED_BITS;
            OUTREG32((PULONG)&g_pBLRegs->int_set_clr, (TempVal & ~FPGA_INT_BIT(nInt)));

            break;
        }
    }

    // If we see the PCCARD client IRQ asserted, look to see if the card is present in the
    // slot.  The MainstoneII PCCARD FPGA implementation is asserting the client IRQ upon
    // card removal which can cause problems down the line when we try to read from the card.
    //
    if (nInt == IRQ_GPIO0_PCMCIA_S0)
    {
        if (g_pBLRegs->pcmcia0_srcr & PCMCIA_S0_nCD_MASK) nInt = IRQ_GPIO0;
    }
    if (nInt == IRQ_GPIO0_PCMCIA_S1)
    {
        if (g_pBLRegs->pcmcia1_srcr & PCMCIA_S1_nCD_MASK) nInt = IRQ_GPIO0;
    }

    // *** The following is to work around a problem in the MainstoneII FPGA ***
    //
    // Bulverde requires a minimum GPIO0 deassertion period before the GPIO0
    // signal can be reasserted.  Failure to comply can lead to problems with 
    // GPIO0 interrupt detection.  As well, because the FPGA interrupt masking
    // operation is a non-atomic read-modify-write operation, it's possible
    // that an async FPGA interrupt can assert during that sequence which
    // in turn violates Bulverde's GPIO0 timing requirements.
    //

    // 1.  First, we'll save off the current interrupt mask (it will be later restored).
    TempVal = (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);

    // 2.  Disable all FPGA interrupts (disable FPGA GPIO0 assertion to Bulverde).
    OUTREG32((PULONG)&g_pBLRegs->int_msk_en,  0);

    // 3.  Clear the Bulverde GPIO0 falling edge detection.
    OUTREG32((PULONG)&g_pGPIORegs->GEDR0, XLLP_GPIO_BIT_0);

    // 4.  Wait...
    OALStall(1);

    // 5.  Restore the FPGA mask (this will cause any pending interrupts to assert
    //     to the Bulverde).
    OUTREG32((PULONG)&g_pBLRegs->int_msk_en,  TempVal);

    return((nInt <= IRQ_MAINSTONEII_GPIO0_MAX) ? nInt : irq);
}

//------------------------------------------------------------------------------
//
//  Function:  GPIOInterruptHandler
//
//  This function is called from the BSP ISR to handle an FPGA interrupt.
//  NOTE: This function only handles the pen detect GPIO.
//
static UINT32 GPIOInterruptHandler(UINT32 irq)
{
	UINT32 retval = 0;
	volatile BULVERDE_INTR_REG *pIntrRegs = NULL;

    pIntrRegs   = (volatile BULVERDE_INTR_REG *) OALPAtoVA(BULVERDE_BASE_REG_PA_INTC, FALSE);
    g_pGPIORegs = (volatile BULVERDE_GPIO_REG *) OALPAtoVA(BULVERDE_BASE_REG_PA_GPIO, FALSE);

    // Disable GPIO interrupts
	pIntrRegs->icmr &= ~XLLP_INTC_GPIOXX_2;

#if !WM_MAINSTONEII_FPGA_PEN_DETECT
    // Check for the pen down interrupt.
    if ( g_pGPIORegs->PEN_DETECT_GPIO_REG(GEDR) & 
         PEN_DETECT_GPIO_MASK 
       )
	{
        // Set the pen down GPIO bit to clear the edge detect status.
        g_pGPIORegs->PEN_DETECT_GPIO_REG(GEDR) = 
            GPIO_BIT(PEN_DETECT_GPIO_NUM);

        // Disable the Rising-Edge detect of the pen down GPIO.
        g_pGPIORegs->PEN_DETECT_GPIO_REG(GRER) &= 
            ~GPIO_BIT(PEN_DETECT_GPIO_NUM);

		retval = IRQ_GPIOXX_2_PEN_DETECT;
	}
#endif // !WM_MAINSTONEII_FPGA_PEN_DETECT

    // Enable GPIO interrupts.
	pIntrRegs->icmr |= XLLP_INTC_GPIOXX_2;

    return(retval);
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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