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

📄 intr.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 2 页
字号:
        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)));
        }
    }

    OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OALIntrDoneIrqs\r\n"));
}


//------------------------------------------------------------------------------
//
//  Function:  OEMInterruptHandler
//
ULONG OEMInterruptHandler(ULONG ra)
{
    UINT32 irq = OAL_INTR_IRQ_UNDEFINED;
    UINT32 sysIntr = SYSINTR_NOP;

    if (!g_pICReg) {
        return(SYSINTR_NOP);
    }

    // Determine the IRQ of the highest priority pending interrupt
    irq = (UINT16)((g_pICReg->ichp >> 16) & 0x3F);

    if (irq == 0)
    {
        return(SYSINTR_NOP);
    }

    // System timer interrupt?
    if (irq == IRQ_OSMR0)
    {
        // The rest is up to the timer interrupt handler.
        //
        sysIntr = OALTimerIntrHandler();

    }
    // Profiling timer interrupt?
    else if (irq == IRQ_OSMR2)
    {
        // Mask the interrupt
        CLRREG32(&g_pICReg->icmr, (1 << irq));

        // The rest is up to the profiling interrupt handler (if profiling
        // is enabled).
        //
        if (g_pProfilerISR) {
            sysIntr = g_pProfilerISR(ra);
        }
    }
    // Board-level interrupts
    else
    {
#ifdef OAL_BSP_CALLBACKS
        UINT32 origIrq = irq;  // save the original so we can tell if it's BSP specific irq
        
        if (irq == IRQ_GPIO0 || irq == IRQ_GPIO1 || irq == IRQ_GPIOXX_2)
        {
            // Give BSP chance to translate IRQ -- if there is subordinate
            // interrupt controller in BSP it give chance to decode its status
            // and change IRQ
            irq = BSPIntrActiveIrq(irq);

            // if irq equals IRQ_GPIOXX_2 demultiplex it to a particular emulated GPIO IRQ if it's not a BSP specific IRQ
            if (irq == IRQ_GPIOXX_2 && origIrq== irq) {
                
                // find the GPIO IRQ
                irq = FindIRQ_GPIOXX_2();

                if (irq != OAL_INTR_IRQ_UNDEFINED)
                {
                    // Mask the interrupt
                    CLRREG32(&g_pICReg->icmr, (1 << IRQ_GPIOXX_2));
                    
                    //clear the GEDRx bit otherwise this ISR will be called again
                    ClearGPIOIrq(irq);

                    // Unmask the interrupt
                    SETREG32(&g_pICReg->icmr, (1 << IRQ_GPIOXX_2));
                }
            }
            else if (irq == IRQ_GPIO1 && origIrq== irq) {
                //clear the GEDRx bit otherwise this ISR will be called again
                g_pGpioRegs->GEDR0 = 1u << 1;
            }
        }
        else
#endif
        {
            // Mask the interrupt
            if ((irq >= IRQ_WTM) && (irq <= IRQ_CAMQCKCAP))
            {
                CLRREG32(&g_pICReg->icmr2, (1 << (irq - IRQ_WTM)));
            }
            else
            {
                CLRREG32(&g_pICReg->icmr, (1 << irq));
            }
        }

#ifdef OAL_ILTIMING
        if (g_oalILT.active) {
            g_oalILT.interrupts++;
        }        
#endif
        // First find if IRQ is claimed by chain
        sysIntr = (UINT16)NKCallIntChain((UCHAR)irq);
        
        //installable ISR returned SYSINTR_NOP?
        if (SYSINTR_NOP == sysIntr)
        {
#ifdef OAL_BSP_CALLBACKS
            if (origIrq != irq) {
                // BSP specific irq
                BSPIntrEnableIrq (irq);
            } else
#endif
            {
                //no additional processing is required.
                //Unmask the interrupt
                if (irq <= IRQ_RTCALARM) {
                    SETREG32(&g_pICReg->icmr, (1 << irq));
                }
                else if ((irq >= IRQ_WTM) && (irq <= IRQ_CAMQCKCAP)) {
                    SETREG32(&g_pICReg->icmr2, (1 << (irq - IRQ_WTM)));
                }
            }
            
            return SYSINTR_NOP;
        }
        
        if (sysIntr == (UINT16)SYSINTR_CHAIN || !NKIsSysIntrValid(sysIntr))
        {
            // IRQ wasn't claimed, use static mapping
            sysIntr = OALIntrTranslateIrq(irq);
        }

        // unmask interrupts in case it's NOP or invalid
        if (SYSINTR_NOP == sysIntr) {
#ifdef OAL_BSP_CALLBACKS
            if (origIrq != irq) {
                // BSP specific irq
                BSPIntrEnableIrq (irq);
            } else
#endif
            {
                // Unmask the interrupt
                if (irq <= IRQ_RTCALARM) {
                    SETREG32(&g_pICReg->icmr, (1 << irq));
                }
                else if ((irq >= IRQ_WTM) && (irq <= IRQ_CAMQCKCAP)) {
                    SETREG32(&g_pICReg->icmr2, (1 << (irq - IRQ_WTM)));
                }
            }
        }
    }

    return (sysIntr);
}


//------------------------------------------------------------------------------
//
//  Function:  OEMInterruptHandlerFIQ
//
void OEMInterruptHandlerFIQ()
{
}

//------------------------------------------------------------------------------
//
//  Function:  disables a GPIO Irq by clearing the corresponding GFERx and GRERx bits
//
void DisableGPIOIrq(UINT32 irq)
{
    if (IRQ_GPIOXX_2_GPIO2 <= irq && irq <= IRQ_GPIOXX_2_GPIO31) {
        g_pGpioRegs->GFER0 &= ~(1 << (irq +2 - IRQ_GPIOXX_2_GPIO2));
        g_pGpioRegs->GRER0 &= ~(1 << (irq +2 - IRQ_GPIOXX_2_GPIO2));
    }
    else if (IRQ_GPIOXX_2_GPIO32 <= irq && irq <= IRQ_GPIOXX_2_GPIO63) {
        g_pGpioRegs->GFER1 &= ~(1 << (irq - IRQ_GPIOXX_2_GPIO32));
        g_pGpioRegs->GRER1 &= ~(1 << (irq - IRQ_GPIOXX_2_GPIO32));
    }
    else if (IRQ_GPIOXX_2_GPIO64 <= irq && irq <= IRQ_GPIOXX_2_GPIO95)  {
        g_pGpioRegs->GFER2 &= ~(1 << (irq - IRQ_GPIOXX_2_GPIO64));
        g_pGpioRegs->GRER2 &= ~(1 << (irq - IRQ_GPIOXX_2_GPIO64));
    }
    else if (IRQ_GPIOXX_2_GPIO96 <= irq && irq <= IRQ_GPIOXX_2_GPIOMAX)  {
        g_pGpioRegs->GFER3 &= ~(1 << (irq - IRQ_GPIOXX_2_GPIO96)) & GPIO_GFER3_VLD_MSK;
        g_pGpioRegs->GRER3 &= ~(1 << (irq - IRQ_GPIOXX_2_GPIO96)) & GPIO_GRER3_VLD_MSK;
    }
}

//------------------------------------------------------------------------------
//
//  Function:  clears a GPIO Irq by clearing the GEDRx bit
//
void ClearGPIOIrq(UINT32 irq)
{

    if (IRQ_GPIOXX_2_GPIO2 <= irq && irq <= IRQ_GPIOXX_2_GPIO31)
        g_pGpioRegs->GEDR0 = 1 << (irq +2 - IRQ_GPIOXX_2_GPIO2);
    else if (IRQ_GPIOXX_2_GPIO32 <= irq && irq <= IRQ_GPIOXX_2_GPIO63)
        g_pGpioRegs->GEDR1 = 1 << (irq - IRQ_GPIOXX_2_GPIO32);
    else if (IRQ_GPIOXX_2_GPIO64 <= irq && irq <= IRQ_GPIOXX_2_GPIO95)
        g_pGpioRegs->GEDR2 = 1 << (irq - IRQ_GPIOXX_2_GPIO64);
    else if (IRQ_GPIOXX_2_GPIO96 <= irq && irq <= IRQ_GPIOXX_2_GPIOMAX)
        g_pGpioRegs->GEDR3 = (1 << (irq - IRQ_GPIOXX_2_GPIO96));
}

//------------------------------------------------------------------------------
//
//  Function:  returns the position of the first least significant bit set to 1.
//                 ex: for 0b000010  returns 1
//                           0b010100  returns 2
//                           0b011111  returns 0
//
UINT32 FirstSetBitPos(UINT32 val)
{
    UINT32 pos = 0;

    if (!val) return -1;
    
    //zero out all high order bits that are 1 except the lowest one
    val &= (INT32)(0-val);
    for (;;)
        {
            switch (val)
                {
                case 1: return pos;
                case 2: return pos+1;
                case 4: return pos+2;
                case 8: return pos+3;
                case 16: return pos+4;
                case 32: return pos+5;
                case 64: return pos+6;
                case 128: return pos+7;
                default: 
                    val >>= 8;
                    pos += 8;
                }
        }
}


//------------------------------------------------------------------------------
//
//  Function:  Find_GPIOXX_2_IRQ
//
//  looks up GEDRx registers to find the GPIO Pin which caused interrupt
//  Note: The algo below gives GPIOx higher priority over GPIOy where x < y.
//
UINT32 FindIRQ_GPIOXX_2()
{
    //look up GEDR to find the GPIO Pin that caused interrupt
    UINT32 retIrq = OAL_INTR_IRQ_UNDEFINED;
    UINT32 regVal;

    if (regVal = (g_pGpioRegs->GEDR0 & ~0x03 & GPIO_GEDR0_VLD_MSK)) {     //~0x03 masks GPIO0 and GPIO1 bit positions
        retIrq = FirstSetBitPos(regVal >> 2) + IRQ_GPIOXX_2_GPIO2;
    }
    else if (regVal = (g_pGpioRegs->GEDR1 & GPIO_GEDR1_VLD_MSK)) {
        retIrq = FirstSetBitPos(regVal) + IRQ_GPIOXX_2_GPIO32;
    }
    else if (regVal = (g_pGpioRegs->GEDR2 & GPIO_GEDR2_VLD_MSK)) {
        retIrq = FirstSetBitPos(regVal) + IRQ_GPIOXX_2_GPIO64;
    }
    else if (regVal = (g_pGpioRegs->GEDR3 & GPIO_GEDR3_VLD_MSK)) {
        retIrq = FirstSetBitPos(regVal) + IRQ_GPIOXX_2_GPIO96;
    }
    else { 
        return OAL_INTR_IRQ_UNDEFINED;
    }
    
    if (retIrq < IRQ_GPIOXX_2_GPIOMIN|| retIrq > IRQ_GPIOXX_2_GPIOMAX)
        return OAL_INTR_IRQ_UNDEFINED;

    return retIrq;
}

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

⌨️ 快捷键说明

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