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

📄 intr.c

📁 realtek562x系列驱动源码。wince
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
//  File:  intr.h
//
//  This file contains MainstoneII board specific interrupt code.
//
#include <bsp.h>
#include <intr_fpga.h>
#include <RTConfig.h>

static UINT32 FPGAInterruptHandler(UINT32 ra);
static void EnableGPIO1Irq(void);
static void DisableGPIO1Irq(void);
static void ClearGPIO1Irq(void);

static volatile MAINSTONEII_BLR_REGS *g_pBLRegs = NULL;
static volatile BULVERDE_GPIO_REG    *g_pGPIORegs = NULL;

#if USE_RESET_PIN_AS_PENDOWN

#define	IRQ_GPIOXX_2_RESET_TO_PENDOWN	IRQ_GPIO0_PENIRQ

static UINT32 GPIOXX_2_InterruptHandler(UINT32 irq);

#endif

//------------------------------------------------------------------------------
//
//  Function:  BSPIntrInit
//
BOOL BSPIntrInit()
{
    volatile BULVERDE_INTR_REG *pIntrRegs = NULL;

    OALMSG(OAL_INTR&&OAL_FUNC, (L"+BSPIntrInit\r\n"));

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

    // Mask and clear all FPGA interrupts.
    //
    g_pBLRegs->int_msk_en  = 0;
    g_pBLRegs->int_set_clr = 0;

    // Enable USB Cable detection interrupts
    OUTREG32((PULONG)&g_pBLRegs->int_msk_en, FPGA_INT_BIT(IRQ_GPIO0_USBCD));

    // Enable GPIO 0 for falling edge (Active Low) to signal the FPGA interrupts.
    //
    SETREG32((PULONG)&g_pGPIORegs->GFER0, XLLP_GPIO_BIT_0);
    SETREG32((PULONG)&pIntrRegs->icmr, (1 << IRQ_GPIO0));
#if USE_RESET_PIN_AS_PENDOWN

	SETREG32((PULONG)&pIntrRegs->icmr, (1 << IRQ_GPIOXX_2));

#endif
    // Set up static interrupt mappings
    OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBOHCI);
#if USE_RESET_PIN_AS_PENDOWN
	
	OALIntrStaticTranslate(SYSINTR_TOUCH,IRQ_GPIOXX_2_RESET_TO_PENDOWN);

#else

    OALIntrStaticTranslate(SYSINTR_TOUCH, IRQ_GPIO0_UCB1400);

#endif
    OALIntrStaticTranslate(SYSINTR_TOUCH_CHANGED, IRQ_OSMR1);
    OALIntrStaticTranslate(SYSINTR_KEYPAD, IRQ_KEYPAD);

    OALIntrStaticTranslate(SYSINTR_FFUART, IRQ_FFUART);
    OALIntrStaticTranslate(SYSINTR_BFUART, IRQ_BTUART);
    OALIntrStaticTranslate(SYSINTR_SFUART, IRQ_STUART);

    OALIntrStaticTranslate(SYSINTR_PCCARD_CSC_S0, IRQ_GPIO0_PCMCIA_S0_CSC);
    OALIntrStaticTranslate(SYSINTR_PCCARD_CD_S0, IRQ_GPIO0_PCMCIA_S0_CD);
    OALIntrStaticTranslate(SYSINTR_PCCARD_CSC_S1, IRQ_GPIO0_PCMCIA_S1_CSC);
    OALIntrStaticTranslate(SYSINTR_PCCARD_CD_S1, IRQ_GPIO0_PCMCIA_S1_CD);

    OALIntrStaticTranslate(SYSINTR_AUDIO, IRQ_DMAC);

    OALIntrStaticTranslate(SYSINTR_USBFN, IRQ_USBFN);

    OALIntrStaticTranslate(SYSINTR_PWRBTN, IRQ_GPIO1);

    OALMSG(OAL_INTR&&OAL_FUNC, (L"-BSPIntrInit\r\n"));

    return TRUE;
}

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

BOOL BSPIntrRequestIrqs(DEVICE_LOCATION *pDevLoc, UINT32 *pCount, UINT32 *pIrqs)
{
    BOOL rc = FALSE;

    OALMSG(OAL_INTR&&OAL_FUNC, (
        L"+BSPIntrRequestIrq(0x%08x->%d/%d/0x%08x/%d, 0x%08x, 0x%08x)\r\n", 
        pDevLoc, pDevLoc->IfcType, pDevLoc->BusNumber, pDevLoc->LogicalLoc,
        pDevLoc->Pin, pCount, pIrqs
    ));

    // Check for input params
    if (pIrqs == NULL || pCount == NULL || *pCount < 1) goto Done;

    switch (pDevLoc->IfcType) {
    case Internal:
        switch ((ULONG)pDevLoc->LogicalLoc) {
        case (MAINSTONEII_BASE_REG_PA_SMSC_ETHERNET + 0x300):
            pIrqs[0] = IRQ_GPIO0_ETHERNET;
            *pCount = 1;
            rc = TRUE;
            break;
        }
        break;
    }

Done:
    OALMSG(OAL_INTR&&OAL_FUNC, (L"-BSPIntrRequestIrq(rc = %d)\r\n", rc));
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function:  BSPIntrEnableIrq
//
//  This function is called from OALIntrEnableIrq to enable interrupt on
//  secondary interrupt controller.
//
UINT32 BSPIntrEnableIrq(UINT32 irq)
{
    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+BSPIntrEnableIrq(%d)\r\n", irq));

    // 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)));

        // Enabling the interrupt at the FPGA controller is enough - no need to enable the Bulverde GPIO0 interrupt.
        irq = OAL_INTR_IRQ_UNDEFINED;
    }
    else if(irq == IRQ_GPIO1)
    {
        EnableGPIO1Irq();
    }
#if USE_RESET_PIN_AS_PENDOWN

	if ( g_pGPIORegs && ( IRQ_GPIOXX_2_RESET_TO_PENDOWN == irq ) )
	{
		g_pGPIORegs->GRER3 |= (XLLP_GPIO_BIT_AC97_RESET_n);
	}

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

//------------------------------------------------------------------------------
//
//  Function:  BSPIntrDisableIrq
//
//  This function is called from OALIntrDisableIrq to disable interrupt on
//  secondary interrupt controller.
//
UINT32 BSPIntrDisableIrq(UINT32 irq)
{
    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+BSPIntrDisableIrq(%d)\r\n", irq));

    // 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;
    }
    else if(irq == IRQ_GPIO1)
    {
        DisableGPIO1Irq();
    }
#if USE_RESET_PIN_AS_PENDOWN

	if ( g_pGPIORegs && ( IRQ_GPIOXX_2_RESET_TO_PENDOWN == irq ) )
	{
		g_pGPIORegs->GRER3 &= ~(XLLP_GPIO_BIT_AC97_RESET_n);
	}

#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.
//
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 USE_RESET_PIN_AS_PENDOWN

	if ( g_pGPIORegs && ( IRQ_GPIOXX_2_RESET_TO_PENDOWN == irq ) )
	{
		g_pGPIORegs->GRER3 |= (XLLP_GPIO_BIT_AC97_RESET_n);
	}

#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:
        ClearGPIO1Irq();
        break;

    case IRQ_GPIOXX_2:
    
#if USE_RESET_PIN_AS_PENDOWN

		irq = GPIOXX_2_InterruptHandler(irq);

		break;
#endif    

    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:  Enables the GPIO1 Irq by setting the corresponding GFERx and GRERx bits
//
static void EnableGPIO1Irq(void)
{
    SETREG32((PULONG)&g_pGPIORegs->GFER0, XLLP_GPIO_BIT_1);
    SETREG32((PULONG)&g_pGPIORegs->GRER0, XLLP_GPIO_BIT_1);
}

//------------------------------------------------------------------------------
//
//  Function:  disables the GPIO1 Irq by clearing the corresponding GFERx and GRERx bits
//
static void DisableGPIO1Irq(void)
{
    CLRREG32((PULONG)&g_pGPIORegs->GFER0, XLLP_GPIO_BIT_1);
    CLRREG32((PULONG)&g_pGPIORegs->GRER0, XLLP_GPIO_BIT_1);
}

//------------------------------------------------------------------------------
//
//  Function:  clears the GPIO1 Irq by clearing the GEDRx bit
//
static void ClearGPIO1Irq(void)
{
    g_pGPIORegs->GEDR0 = XLLP_GPIO_BIT_1;
}

#if USE_RESET_PIN_AS_PENDOWN

static UINT32 GPIOXX_2_InterruptHandler(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 GPIOXX_2 interrupts
	pIntrRegs->icmr &= ~XLLP_INTC_GPIOXX_2;

    // Check have pendown status of the reset-to-pendown pin
    if ( g_pGPIORegs->GEDR3 & (XLLP_GPIO_BIT_AC97_RESET_n))
	{
        //Clear the edge detect status of the reset-to-pendown pin.
        g_pGPIORegs->GEDR3 |=(XLLP_GPIO_BIT_AC97_RESET_n);

        // Disable the Rising-Edge detect of the reset-to-pendown pin
        g_pGPIORegs->GRER3 &= ~(XLLP_GPIO_BIT_AC97_RESET_n);
		
		//return pendown IRQ
		retval = IRQ_GPIOXX_2_RESET_TO_PENDOWN;
	}

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

//RETAILMSG (1, (TEXT("GPIOXX_2_InterruptHandler,retval=%d\r\n"),retval));

    return(retval);
}

#endif

⌨️ 快捷键说明

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