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

📄 intr.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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.c
//
//  This file implement major part of interrupt module for the Intel PXA27x SoC.
//
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <nkexport.h>
#include <bulverde.h>
#include "oal_log.h"
#include "oal_memory.h"
#include "oal_io.h"
#include "oal_timer.h"
#include "oal_intr.h"
#include <intr.h>
#include <oal_ilt.h>

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

// External Functions

// External Variables 
 
// Defines 
#define NUM_INT_PRIOS    32

// Types
 
// Global Variables 
PFN_PROFILER_ISR g_pProfilerISR = NULL;

static volatile BULVERDE_GPIO_REG *g_pGpioRegs  = NULL;
static volatile BULVERDE_INTR_REG *g_pICReg = NULL;
static UINT32   g_IntPriorities[NUM_INT_PRIOS] =
{
    IRQ_OSMR0,         // M0 - Scheduler - ID 26
    IRQ_PMU,           // PMU - ID 12
    IRQ_OSMR2,         // M2 - Profiler - ID 28
    IRQ_OSMR3,         // M3 - DVM - ID 29
    IRQ_GPIO1,         // GPIO1 edge detect - Suspend/Resume - ID 9
    IRQ_RTCALARM,      // RTC Alarm - ID 31
    IRQ_BASEBAND,      // Baseband - ID 1
    IRQ_DMAC,          // DMA Controller - ID 25
    0x00000020,        // Trusted Platform Module (Caddo) - ID 32
    0x00000021,        // Camera Capture - ID 33
    IRQ_USBFN,         // UDC - ID 11
    IRQ_USBOHCI,       // USB Host (OHCI) - ID 3
    IRQ_USBNONOHCI,    // USB Host Non-OHCI - ID 2
    IRQ_OSMRXX_4,      // M4-M11 - ID 7
    IRQ_FFUART,        // FFUART - ID 22
    IRQ_STUART,        // STDUART - ID 20
    IRQ_BTUART,        // BTUART - ID 21
    IRQ_AC97,          // AC97 - UCB1400 - ID 14
    IRQ_OSMR1,         // M1 - Touch Timer (Draw) - ID 27
    IRQ_GPIO0,         // GPIO0 - FPGA - ID 8
    IRQ_MMC,           // MMC - ID 23
    IRQ_MEMSTICK,      // Memstick - ID 5
    IRQ_USIM,          // USIM (Smart Card) - ID 15
    IRQ_GPIOXX_2,      // single interrupt for GPIO Pins 2:120
    0x00000000, 
    0x00000000,
    0x00000000, 
    0x00000000, 
    0x00000000,
    0x00000000, 
    0x00000000, 
    0x00000000
};

static UINT32   g_IntPriorities2[2] =
{
    0x00000000,        // Priorities configured in priorit 2 register.
    IRQ_KEYPAD         //    "
};

// Local Variables 

// Local Functions 
void DisableGPIOIrq(UINT32 irq);
void ClearGPIOIrq(UINT32 irq);
UINT32 FindIRQ_GPIOXX_2();
UINT32 FirstSetBitPos(UINT32 val);


//------------------------------------------------------------------------------
//
//  Function:  OALIntrInit
//
//  This function initialize interrupt mapping, hardware and call platform
//  specific initialization.
//

BOOL OALIntrInit()
{
    BOOL rc = FALSE;
    UINT8 nIntPrio;
    
    OALMSG( OAL_FUNC&&OAL_INTR, (L"+OALInterruptInit\r\n") );

    // Initialize interrupt mapping
    OALIntrMapInit();

    // Map a pointer to the GPIO regs
    //
    g_pGpioRegs  = (volatile BULVERDE_GPIO_REG *) OALPAtoUA(BULVERDE_BASE_REG_PA_GPIO);

    // Map a pointer to the interrupt controller.
    //
    g_pICReg = (volatile BULVERDE_INTR_REG *) OALPAtoVA(BULVERDE_BASE_REG_PA_INTC, FALSE);

    // Configure interrupt priorities.
    //
    for (nIntPrio = 0 ; nIntPrio < NUM_INT_PRIOS ; nIntPrio++)
    {
        g_pICReg->ipr[nIntPrio] = ((1 << 31) | g_IntPriorities[nIntPrio]);
    }
    g_pICReg->ipr2[0] = ((1 << 31) | g_IntPriorities2[0]);
    g_pICReg->ipr2[1] = ((1 << 31) | g_IntPriorities2[1]);

    //
    // Set DIM, the only bit in the ICCR.  
    // The effect is that only enabled and unmasked
    // interrupts bring the processor out of IDLE mode.
    //
    g_pICReg->iccr = 0x1;

#ifdef OAL_BSP_CALLBACKS
    // Give BSP change to initialize subordinate controller
    rc = BSPIntrInit();
#else
    rc = TRUE;
#endif

    // Setup static interrupt mappings (first one isn't really needed)
    OALIntrStaticTranslate(SYSINTR_RESCHED, IRQ_OSMR0);
    OALIntrStaticTranslate(SYSINTR_RTC_ALARM, IRQ_RTCALARM);

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



//------------------------------------------------------------------------------
//
//  Function:  OALIntrRequestIrqs
//
//  This function returns IRQ for CPU/SoC devices based on their
//  physical address.
//
BOOL OALIntrRequestIrqs(DEVICE_LOCATION *pDevLoc, UINT32 *pCount, UINT32 *pIrqs)
{
    BOOL rc = FALSE;

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

    // This shouldn't happen
    if (*pCount < 1) goto cleanUp;

#ifdef OAL_BSP_CALLBACKS
    rc = BSPIntrRequestIrqs(pDevLoc, pCount, pIrqs);
#endif    

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


//------------------------------------------------------------------------------
//
//  Function:  OALIntrEnableIrqs
//
BOOL OALIntrEnableIrqs(UINT32 count, const UINT32 *pIrqs)
{
    BOOL rc = TRUE;
    UINT32 irq, i;


    OALMSG(OAL_INTR&&OAL_FUNC, (
        L"+OALIntrEnableIrqs(%d, 0x%08x)\r\n", count, pIrqs
    ));
    
    for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
        irq = pIrqs[i];
#else
        // Give BSP chance to enable irq on subordinate interrupt controller
        irq = BSPIntrEnableIrq(pIrqs[i]);
        if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
#endif
        if (irq <= IRQ_RTCALARM) {
            // Enable the primary IRQ
            SETREG32(&g_pICReg->icmr, (1 << irq));
        }
        else if ((irq >= IRQ_WTM) && (irq <= IRQ_CAMQCKCAP))
        {
            SETREG32(&g_pICReg->icmr2, (1 << (irq - IRQ_WTM)));
        }
        else if (irq >= IRQ_GPIOXX_2_GPIOMIN && irq <= IRQ_GPIOXX_2_GPIOMAX) {
            //Enable IRQ_GPIOXX_2
            SETREG32(&g_pICReg->icmr, (1 << IRQ_GPIOXX_2));
            //Note: To actually enable this GPIO irq generation make sure
            //the corresponding GRERx/GFERx bits are also set
        } else {
            rc = FALSE;
        }            
    }

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


//------------------------------------------------------------------------------
//
//  Function:  OALIntrDisableIrqs
//
VOID OALIntrDisableIrqs(UINT32 count, const UINT32 *pIrqs)
{
    UINT32 irq, i;

    OALMSG(OAL_INTR&&OAL_FUNC, (
        L"+OALIntrDisableIrqs(%d, 0x%08x)\r\n", count, pIrqs
    ));
    
    for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
        irq = pIrqs[i];
#else
        // Give BSP chance to disable irq on subordinate interrupt controller
        irq = BSPIntrDisableIrq(pIrqs[i]);
#endif
        if (irq <= IRQ_RTCALARM) {
            // Disable the primary IRQ
            CLRREG32(&g_pICReg->icmr, (1 << irq));
        }
        else if ((irq >= IRQ_WTM) && (irq <= IRQ_CAMQCKCAP)) {
            CLRREG32(&g_pICReg->icmr2, (1 << (irq - IRQ_WTM)));
        }
        else if (irq >= IRQ_GPIOXX_2_GPIOMIN && irq <= IRQ_GPIOXX_2_GPIOMAX) {
            //Clear GRERx and GFERx bit disabling interrupt generation.
            //Note: Since the next line clears the GRERx and GFERx bits,
            //to reenable this GPIO irq generation calling OALIntrEnableIrqs
            //is not enough - make sure corresponding GRERx/GFERx bits are also set.
            DisableGPIOIrq(irq);
        }
    }

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


//------------------------------------------------------------------------------
//
//  Function:  OALIntrDoneIrqs
//
VOID OALIntrDoneIrqs(UINT32 count, const UINT32 *pIrqs)
{
    UINT32 irq, i;

    OALMSG(OAL_INTR&&OAL_VERBOSE, (
        L"+OALIntrDoneIrqs(%d, 0x%08x)\r\n", count, pIrqs
    ));

    for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
        irq = pIrqs[i];
#else
        // Give BSP chance to finish irq on subordinate interrupt controller
        irq = BSPIntrDoneIrq(pIrqs[i]);
        if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
#endif

⌨️ 快捷键说明

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