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

📄 intr.c

📁 6410BSP1
💻 C
📖 第 1 页 / 共 3 页
字号:
    // 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 bRet = TRUE;
    UINT32 VirtualIRQ;
    UINT32 PhysicalIRQ;
    UINT32 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
        VirtualIRQ = pIrqs[i];
#else
        // Give BSP chance to enable irq on subordinate interrupt controller
        VirtualIRQ = BSPIntrEnableIrq(pIrqs[i]);
#endif

        if (VirtualIRQ == OAL_INTR_IRQ_UNDEFINED) continue;

        // Translate to Physical IRQ
        PhysicalIRQ = g_VirIrq2PhyIrq[VirtualIRQ];

        if (PhysicalIRQ == PHYIRQ_EINT0 ||  // IRQ_EINT0 ~ IRQ_EINT3
            PhysicalIRQ == PHYIRQ_EINT1 )   // IRQ_EINT4 ~ IRQ_EINT11
        {
            g_pGPIOReg->EINT0MASK &= ~(1<<VirtualIRQ);   // Enable Sub Interrupt
            g_pGPIOReg->EINT0PEND = (1<<VirtualIRQ);     // Clear Sub Pending
        }
        else if (PhysicalIRQ == PHYIRQ_EINT2 || // IRQ_EINT12 ~ IRQ_EINT19
                 PhysicalIRQ == PHYIRQ_EINT3 )  // IRQ_EINT20 ~ IRQ_EINT27
        {
            g_pGPIOReg->EINT0MASK &= ~(1<<(VirtualIRQ-30));   // Enable Sub Interrupt
            g_pGPIOReg->EINT0PEND = (1<<(VirtualIRQ-30));     // Clear Sub Pending
        }
        else if (PhysicalIRQ < VIC1_BIT_OFFSET)
        {
            g_pVIC0Reg->VICINTENABLE = (0x1<<PhysicalIRQ);
        }
        else if (PhysicalIRQ < PHYIRQ_MAX_S3C6410)
        {
            g_pVIC1Reg->VICINTENABLE = (0x1<<(PhysicalIRQ-VIC1_BIT_OFFSET));
        }
        else
        {
            bRet = FALSE;
        }
    }

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

    return bRet;
}

//------------------------------------------------------------------------------
//
//  Function:  OALIntrDisableIrqs
//
VOID OALIntrDisableIrqs(UINT32 count, const UINT32 *pIrqs)
{
    UINT32 VirtualIRQ;
    UINT32 PhysicalIRQ;
    UINT32 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
        VirtualIRQ = pIrqs[i];
#else
        // Give BSP chance to disable irq on subordinate interrupt controller
        VirtualIRQ = BSPIntrDisableIrq(pIrqs[i]);
#endif
        if (VirtualIRQ == OAL_INTR_IRQ_UNDEFINED) continue;

        // Translate to Physical IRQ
        PhysicalIRQ = g_VirIrq2PhyIrq[VirtualIRQ];

        if (PhysicalIRQ == PHYIRQ_EINT0 ||  // IRQ_EINT0 ~ IRQ_EINT3
            PhysicalIRQ == PHYIRQ_EINT1 )   // IRQ_EINT4 ~ IRQ_EINT11
        {
            g_pGPIOReg->EINT0MASK |= (1<<VirtualIRQ);    // Mask Sub Interrupt
            g_pGPIOReg->EINT0PEND = (1<<VirtualIRQ);    // Clear Sub Pending

            // Do not Mask PHYIRQ_EINT0/1 Interrupt !!!
        }
        else if (PhysicalIRQ == PHYIRQ_EINT2 || // IRQ_EINT12 ~ IRQ_EINT19
                 PhysicalIRQ == PHYIRQ_EINT3 )  // IRQ_EINT20 ~ IRQ_EINT27
        {
            
            g_pGPIOReg->EINT0MASK |= (1<<(VirtualIRQ-30));    // Mask Sub Interrupt
            g_pGPIOReg->EINT0PEND = (1<<(VirtualIRQ-30));    // Clear Sub Pending

            // Do not Mask PHYIRQ_EINT2/3 Interrupt !!!
        }
        else if (PhysicalIRQ == PHYIRQ_DMA0)
        {
            // Do not Mask PHYIRQ_DMA0 Interrupt !!!
        }
        else if (PhysicalIRQ == PHYIRQ_DMA1)
        {
            // Do not Mask PHYIRQ_DMA1 Interrupt !!!
        }
        else if (PhysicalIRQ < VIC1_BIT_OFFSET)
        {
            g_pVIC0Reg->VICINTENCLEAR = (0x1<<PhysicalIRQ);
        }
        else if (PhysicalIRQ < PHYIRQ_MAX_S3C6410)
        {
            g_pVIC1Reg->VICINTENCLEAR = (0x1<<(PhysicalIRQ-VIC1_BIT_OFFSET));
        }
    }

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

//------------------------------------------------------------------------------
//
//  Function:  OALIntrDoneIrqs
//
VOID OALIntrDoneIrqs(UINT32 count, const UINT32 *pIrqs)
{
    UINT32 VirtualIRQ;
    UINT32 PhysicalIRQ;
    UINT32 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
        VirtualIRQ = pIrqs[i];
#else
        // Give BSP chance to finish irq on subordinate interrupt controller
        VirtualIRQ = BSPIntrDoneIrq(pIrqs[i]);
#endif

        // Translate to Physical IRQ
        PhysicalIRQ = g_VirIrq2PhyIrq[VirtualIRQ];

        if (PhysicalIRQ == PHYIRQ_EINT0 ||  // IRQ_EINT0 ~ IRQ_EINT3
            PhysicalIRQ == PHYIRQ_EINT1)    // IRQ_EINT4 ~ IRQ_EINT11
        {
            g_pGPIOReg->EINT0MASK &= ~(1<<VirtualIRQ);   // Enable Sub Interrupt
        }
        else if (PhysicalIRQ == PHYIRQ_EINT2 || // IRQ_EINT12 ~ IRQ_EINT19
                 PhysicalIRQ == PHYIRQ_EINT3 )  // IRQ_EINT20 ~ IRQ_EINT27
        {
            g_pGPIOReg->EINT0MASK &= ~(1<<(VirtualIRQ-30));   // Enable Sub Interrupt
        }
        else if (PhysicalIRQ < VIC1_BIT_OFFSET)
        {
            g_pVIC0Reg->VICINTENABLE = (0x1<<PhysicalIRQ);
        }
        else if (PhysicalIRQ < PHYIRQ_MAX_S3C6410)
        {
            g_pVIC1Reg->VICINTENABLE = (0x1<<(PhysicalIRQ-VIC1_BIT_OFFSET));
        }
    }

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

//------------------------------------------------------------------------------
//
//  Function:  OEMInterruptHandler
//
ULONG OEMInterruptHandler(ULONG ra)
{
    UINT32 SysIntr = SYSINTR_NOP;
    UINT32 PhysicalIRQ;
    UINT32 VirtualIRQ;
    UINT32 uiPending;
    UINT32 uiMask;
    int nNumber;
#ifdef    VIC_MASK
    UINT32 IntEnVIC0, IntEnVIC1;
#endif

    static DWORD HeartBeatCnt, HeartBeatStat;  //LED4 is used for heart beat

    // Get Pending Interrupt Number
    PhysicalIRQ = g_pVIC1Reg->VICADDRESS;    // Ready Dummy from VIC1
    PhysicalIRQ = g_pVIC0Reg->VICADDRESS;

#ifdef    VIC_MASK
    // To Avoid low proirity interrupt lost
    IntEnVIC0 = g_pVIC0Reg->VICINTENABLE;
    IntEnVIC1 = g_pVIC1Reg->VICINTENABLE;
    g_pVIC0Reg->VICINTENCLEAR = 0xffffffff;
    g_pVIC1Reg->VICINTENCLEAR = 0xffffffff;
#endif

    // Translate Physical IRQ to Virtual IRQ (Except Flatten IRQ)
    VirtualIRQ = g_PhyIrq2VirIrq[PhysicalIRQ];

    if (PhysicalIRQ == PHYIRQ_TIMER4)
    {
        //-------------
        // System Timer
        //-------------

        // Heart Beat LED
        if (++HeartBeatCnt >= HEART_BEAT_DURATION)
        {
            HeartBeatCnt = 0;
            HeartBeatStat ^= 1;

            if (HeartBeatStat)
            {
                OEMWriteDebugLED(-1, MAKELONG(0x1, 0x1));
            }
            else
            {
                OEMWriteDebugLED(-1, MAKELONG(0x0, 0x1));
            }
        }

        if (g_pVIC0Reg->VICRAWINTR & (1<<PHYIRQ_TIMER4))
        {
            // Handling System Timer Interrupt
            SysIntr = OALTimerIntrHandler();
        }
        else
        {
            OALMSG(TRUE, (L"[OAL:ERR] PHYIRQ_TIMER4 Interrupt But There is No Pending !!!!\r\n"));
        }

    }
    else if (PhysicalIRQ == PHYIRQ_TIMER2)
    {
        //-------------
        // Profiling Timer
        //-------------

        // Masking Interrupt
#ifdef    VIC_MASK
        IntEnVIC0 &= ~(1<<PHYIRQ_TIMER2);
#else
        g_pVIC0Reg->VICINTENCLEAR = (1<<PHYIRQ_TIMER2);
#endif

        // Handling Profiling Timer Interrupt
        if (g_pProfilerISR)
        {
            SysIntr = g_pProfilerISR(ra);
        }
    }
    else
    {
#ifdef OAL_ILTIMING
        if (g_oalILT.active)
        {
            g_oalILT.isrTime1 = OALTimerCountsSinceSysTick();
            g_oalILT.savedPC = 0;
            g_oalILT.interrupts++;
        }
#endif

        if (PhysicalIRQ == PHYIRQ_EINT0)
        {
            // Do not mask PHYIRQ_EINT0 interrupt for other sub interrupt
            // Mask EINTMASK and EINTPEND which occured this time
            // So each IST of EINT should unmask their EINT for Next Interrupt

            // Check Sub Source and Mask
            uiPending = g_pGPIOReg->EINT0PEND;
            uiMask = g_pGPIOReg->EINT0MASK;

            for (nNumber=0; nNumber<4; nNumber++)    // EINT0~EINT3
            {
                if ((uiPending & (1<<nNumber)) && !(uiMask & (1<<nNumber)))
                {
                    g_pGPIOReg->EINT0MASK |= (1<<nNumber);    // Mask Sub Interrupt
                    g_pGPIOReg->EINT0PEND = (1<<nNumber);        // Clear Sub Pending
                    VirtualIRQ = (IRQ_EINT0+nNumber);                // Set Virtual IRQ
                    break;
                }
            }
        }
        else if (PhysicalIRQ == PHYIRQ_EINT1)
        {
            // Do not mask PHYIRQ_EINT1 interrupt for other sub interrupt
            // Mask EINTMASK and EINTPEND which occured this time
            // So each IST of EINT should unmask their EINT for Next Interrupt

            // Check Sub Source
            uiPending = g_pGPIOReg->EINT0PEND;

⌨️ 快捷键说明

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