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

📄 intr.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File:  intr.h
//
//  This file contains XSBASE270_G board specific interrupt code.
//
#include <bsp.h>

#define IRQ_GPIO9_IDE		      (IRQ_BULVERDE_MAX + 14)  // 45
#define IRQ_GPIO22_PCMCIA_S0          (IRQ_BULVERDE_MAX + 12)  // 43
#define IRQ_GPIO1_PCMCIA_S0_CSC       (IRQ_BULVERDE_MAX + 11)  // 42
#define IRQ_GPIO1_PCMCIA_S0_CD        (IRQ_BULVERDE_MAX + 10)  // 41
#define IRQ_GPIO12_MARATHON           (IRQ_BULVERDE_MAX + 9)   // 40
#define IRQ_GPIO17_EXPBD              (IRQ_BULVERDE_MAX + 8)   // 39
#define IRQ_GPIO0_MSINS               (IRQ_BULVERDE_MAX + 7)   // 38
#define IRQ_GPIO13_PENIRQ             (IRQ_BULVERDE_MAX + 6)   // 37
#define IRQ_GPIO13_UCB1400            (IRQ_BULVERDE_MAX + 5)   // 36
#define IRQ_GPIO10_ETHERNET           (IRQ_BULVERDE_MAX + 4)   // 35
#define IRQ_GPIO1_USBCD               (IRQ_BULVERDE_MAX + 3)   // 34
#define IRQ_GPIO1_USIMCD              (IRQ_BULVERDE_MAX + 2)   // 33
#define IRQ_GPIO1_MMCCD               (IRQ_BULVERDE_MAX + 1)   // 32

#define IRQ_XSBASE270_G_GPIO_MIN      IRQ_GPIO1_MMCCD
#define IRQ_XSBASE270_G_GPIO_MAX      IRQ_GPIO9_IDE

#define FPGA_INT_BIT(n)              (1 << (n - IRQ_XSBASE270_G_GPIO_MIN))

static UINT32 FPGAInterruptHandler(UINT32 ra);

static volatile XSBASE270_G_CPLD_REGS *g_pCPLDRegs = NULL;
static volatile BULVERDE_GPIO_REG    *g_pGPIORegs = NULL;

//------------------------------------------------------------------------------
//
//  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_pCPLDRegs = (volatile XSBASE270_G_CPLD_REGS *) OALPAtoVA(XSBASE270_G_BASE_REG_PA_CPLD, FALSE);
    g_pGPIORegs = (volatile BULVERDE_GPIO_REG *) OALPAtoVA(BULVERDE_BASE_REG_PA_GPIO, FALSE);

    // Clear Interrupt Register (CPLD)
    g_pCPLDRegs->INT = 0;

    // Enable GPIO 1 for falling edge (Active Low) to signal the FPGA interrupts.
    //
    SETREG32((PULONG)&g_pGPIORegs->GFER0, XLLP_GPIO_BIT_1);
    SETREG32((PULONG)&pIntrRegs->icmr, (1 << IRQ_GPIO1));

    // Enable GPIO 2-118 Interrupt
    SETREG32((PULONG)&pIntrRegs->icmr, (1 << IRQ_GPIOXX_2));

	OALIntrStaticTranslate(SYSINTR_QUICKIDE, IRQ_GPIO9_IDE);
    // Set up static interrupt mappings
    OALIntrStaticTranslate(SYSINTR_MARATHON, IRQ_GPIO12_MARATHON);
    OALIntrStaticTranslate(SYSINTR_LAN91C111, IRQ_GPIO10_ETHERNET);
    OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBOHCI);
    OALIntrStaticTranslate(SYSINTR_TOUCH, IRQ_GPIO13_UCB1400);
    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_GPIO1_PCMCIA_S0_CSC);
    OALIntrStaticTranslate(SYSINTR_PCCARD_CD_S0, IRQ_GPIO1_PCMCIA_S0_CD);

    OALIntrStaticTranslate(SYSINTR_AUDIO, IRQ_DMAC);

    OALIntrStaticTranslate(SYSINTR_USBFN, IRQ_USBFN);

    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 (XSBASE270_G_BASE_REG_PA_SMSC_ETHERNET + 0x300):
            pIrqs[0] = IRQ_GPIO10_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_pCPLDRegs && (irq >= IRQ_XSBASE270_G_GPIO_MIN) && (irq <= IRQ_XSBASE270_G_GPIO_MAX))
    {
        switch(irq)
        {
        case IRQ_GPIO12_MARATHON:
            //OALMSG(OAL_INTR, (L"IntrEnable: MARATHON\r\n"));
            g_pGPIORegs->GFER0 |= XLLP_BIT_12;
            break;

        case IRQ_GPIO10_ETHERNET:
            // OALMSG(OAL_INTR, (L"IntrEnable: ETHER\r\n"));
            g_pGPIORegs->GRER0 |= XLLP_BIT_10;
            break;
	case IRQ_GPIO9_IDE:
//		OALMSG(1, (L"IntrEnable: ide\r\n\r\n\r\n"));
		g_pGPIORegs->GRER0 |= XLLP_BIT_20;
            break;

        case IRQ_GPIO13_UCB1400:
            // OALMSG(TRUE, (L"IntrEnable: UCB1400\r\n"));
            g_pGPIORegs->GRER0 |= XLLP_BIT_13;
            break;

        case IRQ_GPIO1_PCMCIA_S0_CSC:
            // OALMSG(OAL_INTR, (L"IntrEnable: CF Detect\r\n"));
            g_pGPIORegs->GFER0 |= XLLP_BIT_1;
            break;

        case IRQ_GPIO22_PCMCIA_S0:
            OALMSG(OAL_INTR, (L"IntrEnable: CF IRQ\r\n"));
            g_pGPIORegs->GFER0 |= XLLP_BIT_22;
            break;

        default:
            break;
        }

        irq = OAL_INTR_IRQ_UNDEFINED;
    }

    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_pCPLDRegs && (irq >= IRQ_XSBASE270_G_GPIO_MIN) && (irq <= IRQ_XSBASE270_G_GPIO_MAX))
    {
        switch(irq)
        {
        case IRQ_GPIO12_MARATHON:
            //OALMSG(OAL_INTR, (L"IntrDisable: MARATHON\r\n"));
            g_pGPIORegs->GFER0 &= ~XLLP_BIT_12;
            break;

        case IRQ_GPIO10_ETHERNET:
            // OALMSG(OAL_INTR, (L"IntrDisable: ETHER\r\n"));
            g_pGPIORegs->GRER0 &= ~XLLP_BIT_10;
            g_pGPIORegs->GEDR0 = XLLP_BIT_10;
            break;

	case IRQ_GPIO9_IDE:
//		OALMSG(1, (L"IntrDisable: ide\r\n\r\n"));
		g_pGPIORegs->GRER0 &= ~XLLP_BIT_20;
		g_pGPIORegs->GEDR0 = XLLP_BIT_20;
		break;
        case IRQ_GPIO13_UCB1400:
            // OALMSG(TRUE, (L"IntrDisable: UCB1400\r\n"));
            g_pGPIORegs->GRER0 &= ~XLLP_BIT_13;
            g_pGPIORegs->GEDR0 = XLLP_BIT_13;
            break;

        case IRQ_GPIO1_PCMCIA_S0_CSC:
            // OALMSG(OAL_INTR, (L"IntrDisable: CF Detect\r\n"));
            break;

        case IRQ_GPIO22_PCMCIA_S0:
            OALMSG(OAL_INTR, (L"IntrDisable: CF IRQ\r\n"));
            g_pGPIORegs->GFER0 &= ~XLLP_BIT_22;
            g_pGPIORegs->GEDR0 = XLLP_BIT_22;
            break;

        default:
            break;
        }
        irq = OAL_INTR_IRQ_UNDEFINED;
    }

    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_pCPLDRegs && (irq >= IRQ_XSBASE270_G_GPIO_MIN) && (irq <= IRQ_XSBASE270_G_GPIO_MAX))
    {
        switch(irq)
        {
        case IRQ_GPIO12_MARATHON:
            //OALMSG(OAL_INTR, (L"IntrDone: MARATHON\r\n"));
            g_pGPIORegs->GFER0 |= XLLP_BIT_12;
            break;

        case IRQ_GPIO10_ETHERNET:
            // OALMSG(OAL_INTR, (L"IntrDone: ETHER\r\n"));
            g_pGPIORegs->GRER0 |= XLLP_BIT_10;
            break;

	case IRQ_GPIO9_IDE:
//		OALMSG(1, (L"IntrDone: ide\r\n\r\n"));
		g_pGPIORegs->GRER0 |= XLLP_BIT_20;
            break;

        case IRQ_GPIO13_UCB1400:
            // OALMSG(TRUE, (L"IntrDone: UCB1400\r\n"));
            g_pGPIORegs->GRER0 |= XLLP_BIT_13;
            break;

        case IRQ_GPIO1_PCMCIA_S0_CSC:
            // OALMSG(OAL_INTR, (L"IntrDone: CF Detect\r\n"));
            g_pGPIORegs->GFER0 |= XLLP_BIT_1;
            break;

        case IRQ_GPIO22_PCMCIA_S0:
            OALMSG(OAL_INTR, (L"IntrDone: CF IRQ\r\n"));
            g_pGPIORegs->GFER0 |= XLLP_BIT_22;
            break;

        default:
            break;
        }
        irq = OAL_INTR_IRQ_UNDEFINED;
    }

    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)
{
    UINT irq_det;

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

    switch(irq)
    {
    case IRQ_GPIO0:
        // OALMSG(OAL_INTR, (L"IntrActive: GPIO0\r\n"));
        break;

    case IRQ_GPIO1:
        // OALMSG(OAL_INTR, (L"IntrActive: GPIO1\r\n"));
        irq = FPGAInterruptHandler(irq);
        break;

    case IRQ_GPIOXX_2:
        irq_det = g_pGPIORegs->GEDR0;

        switch(irq_det)
        {
        case XLLP_BIT_12:
            //OALMSG(OAL_INTR, (L"IntrActive: MARATHON\r\n"));
            g_pGPIORegs->GFER0 &= ~XLLP_BIT_12;
            g_pGPIORegs->GEDR0 = XLLP_BIT_12;
            irq = IRQ_GPIO12_MARATHON;
            break;

        case XLLP_BIT_10:
             //OALMSG(1, (L"IntrActive: ETHER\r\n"));
            // g_pGPIORegs->GRER0 &= ~XLLP_BIT_10;
            g_pGPIORegs->GEDR0 = XLLP_BIT_10;
            irq = IRQ_GPIO10_ETHERNET;
            break;

	case XLLP_BIT_9:
//		OALMSG(1, (L"IntrActive: ide\r\n\r\n\r\n"));
		g_pGPIORegs->GRER0 &= ~XLLP_BIT_9;
		g_pGPIORegs->GEDR0 = XLLP_BIT_9;
		irq = IRQ_GPIO9_IDE;
            break;

        case XLLP_BIT_13:
            // OALMSG(TRUE, (L"IntrActive: UCB1400\r\n"));
            g_pGPIORegs->GRER0 &= ~XLLP_BIT_13;
            g_pGPIORegs->GEDR0 = XLLP_BIT_13;
            irq = IRQ_GPIO13_UCB1400;
            break;

        case XLLP_BIT_22:
            // OALMSG(OAL_INTR, (L"IntrActive: CF_IRQ\r\n"));
            // g_pGPIORegs->GFER0 &= ~XLLP_BIT_22;
            g_pGPIORegs->GEDR0 = XLLP_BIT_22;
            if (g_pCPLDRegs->STATUS & STS_CF_DET)
               irq = IRQ_GPIO22_PCMCIA_S0;
            break;

        default:
            break;
        }

        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)
{
    UINT16 TempVal;

    // Disable GPIO1 Interrupt.
    g_pGPIORegs->GFER0 &= ~XLLP_BIT_1;
    g_pGPIORegs->GEDR0 = XLLP_BIT_1;

    // Read the CPLD interrupts register.
    TempVal  = (UINT16)g_pCPLDRegs->INT;

    OALStall(1);

    g_pGPIORegs->GFER0 |= XLLP_BIT_1;

    if((TempVal & INT_CF_IN) || (TempVal & INT_CF_OUT))
    {
        g_pCPLDRegs->INT &= ~(INT_CF_IN | INT_CF_OUT);
        return IRQ_GPIO1_PCMCIA_S0_CSC;
    }
    else if((TempVal & INT_USB_IN) || (TempVal & INT_USB_OUT))
    {
        g_pCPLDRegs->INT &= ~(INT_USB_IN | INT_USB_OUT);
        return IRQ_GPIO1_USBCD;
    }
    else if((TempVal & INT_MMC_IN) || (TempVal & INT_MMC_OUT))
    {
        g_pCPLDRegs->INT &= ~(INT_MMC_IN | INT_MMC_OUT);
        return IRQ_GPIO1_MMCCD;
    }

    return irq;
}

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

⌨️ 快捷键说明

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