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

📄 intr.c

📁 NXP LPC3000系列 wince BSP包
💻 C
📖 第 1 页 / 共 2 页
字号:
//
BOOL OALIntrEnableIrqs(UINT32 count, const UINT32 *pIrqs)
{
    BOOL rc = TRUE;
	UINT32 i, bit_pos;
	INTERRUPT_SOURCE_T lirq;
	INTC_REGS_T *pIntc;

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

	// Enable each IRQ
    for (i = 0; i < count; i++)
	{
		// Out of range?
		if (pIrqs[i] <= OAL_INTR_IRQ_LAST)
		{
			lirq = lp32xx_ierqsupp[pIrqs[i]].lpc32xx_irq_num;
			if (lirq == VIRTINTR)
			{
				// Interrupt is virtual, call virtual interrupt handler
				rc = IntrEnableVirtual((OAL_TO_HW_IRQ_T *) &pIrqs[i], TRUE);
			}
		    else if (int_get_controller(lirq, &pIntc, &bit_pos) == TRUE)
			{
			    // Get the interrupt controller for the given interrupt source
				pIntc->er |= _BIT(bit_pos);
			}
		}
		else
		{
			rc = FALSE;
		}
    }

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

	return rc;    
}

//------------------------------------------------------------------------------
//
// OALIntrDisableIrqs
//
// Disable one or more LPC32XX IRQs.
//
VOID OALIntrDisableIrqs(UINT32 count, const UINT32 *pIrqs)
{
	INTERRUPT_SOURCE_T lirq;
	INTC_REGS_T *pIntc;
	UINT32 i, bit_pos = 0;

    OALMSG((OAL_INTR&&OAL_FUNC), (L"+OALIntrDisableIrqs(%d, 0x%08x)\r\n",
		count, pIrqs));
    
	// Disable each IRQ
    for (i = 0; i < count; i++) {
		// Out of range?
		if (pIrqs[i] <= OAL_INTR_IRQ_LAST)
		{
			lirq = lp32xx_ierqsupp[pIrqs[i]].lpc32xx_irq_num;
			if (lirq == VIRTINTR)
			{
				// Interrupt is virtual, call virtual interrupt handler
				IntrEnableVirtual((OAL_TO_HW_IRQ_T *) &pIrqs[i], FALSE);
			}
		    else if (int_get_controller(lirq, &pIntc, &bit_pos) == TRUE)
			{
			    // Get the interrupt controller for the give interrupt source
				pIntc->er &= ~_BIT(bit_pos);
			}
		}
	}

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

//------------------------------------------------------------------------------
//
// IntrDoneVirtual
//
// Used for clearing and re-enabling virtual interrupts (DMA).
//
static BOOL IntrDoneVirtual(OAL_TO_HW_IRQ_T *pIrqHw)
{
	UINT32 dmaChan, msk;
	BOOL rc = FALSE;

	// For now, these only apply to DMA
	if ((pIrqHw->oal_intr_irq_num >= OAL_INTR_DMACH_0) &&
		(pIrqHw->oal_intr_irq_num <= OAL_INTR_DMACH_6))
	{
		// Get DMA channel
		dmaChan = (UINT32) pIrqHw->oal_intr_irq_num - OAL_INTR_DMACH_0;

		// Only works when DMA channel has been enabled
		msk = _BIT(dmaChan);

		// Clear latched TC and ERR interrupt flags
		pDMARegs->int_tc_clear = msk;
		pDMARegs->int_err_clear = msk;

		// Re-enable channel
		pDMARegs->dma_chan[dmaChan].config_ch |= (DMAC_CHAN_ITC | DMAC_CHAN_IE);

		rc = TRUE;
	}

	return rc;
}

//------------------------------------------------------------------------------
//
// OALIntrDoneIrqs
//
// Re-enable obe or more LPC32xx IRQs.
//
VOID OALIntrDoneIrqs(UINT32 count, const UINT32 *pIrqs)
{
	INTERRUPT_SOURCE_T lirq;
	INTC_REGS_T *pIntc;
	UINT32 i,  bit_pos = 0;

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

    for (i = 0; i < count; i++) {
		// Out of range?
		if (pIrqs[i] <= OAL_INTR_IRQ_LAST)
		{
			lirq = lp32xx_ierqsupp[pIrqs[i]].lpc32xx_irq_num;
			if (lirq == VIRTINTR)
			{
				// Interrupt is virtual, call virtual interrupt handler
				IntrDoneVirtual((OAL_TO_HW_IRQ_T *) &pIrqs[i]);
			}
			else
			{
			    // Get the interrupt controller for the give interrupt source
				if (int_get_controller(lirq, &pIntc, &bit_pos) == TRUE)
				{
					// Clear pending interrupt
					pIntc->rsr = _BIT(bit_pos);

					// Re-enable interrupt
					pIntc->er |= _BIT(bit_pos);
				}
			}
		}
	}

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

//------------------------------------------------------------------------------
//
// OALIntrRequestIrqs
//
// This function returns IRQs 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\r\n"));

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

	switch (pDevLoc->IfcType) {
    case Internal:
        switch ((ULONG)pDevLoc->PhysicalLoc) {
        case ETHERNET_BASE:
            *pCount = 1;
            pIrqs[0] = OAL_INTR_IRQ_ETHERNET;
            rc = TRUE;
            break;
        }
        break;
    }

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

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

//------------------------------------------------------------------------------
//
// OEMInterruptHandler
//
// Handles the LPC32XX interrupts and generates the correct sysIntr values.
//
ULONG OEMInterruptHandler(ULONG ra)
{
	DWORD dirq;
	INTERRUPT_SOURCE_T intsrc;
	INTC_REGS_T *pIntc;
    UINT32 sts, sysIntr = SYSINTR_NOP, bit_pos = 0;

	// Read MIC status masking off IRQ bits
	sts = pMIC->sr & ~(_BIT(IRQ_SUB1IRQ) | _BIT(IRQ_SUB2IRQ) |
		_BIT(IRQ_SUB1FIQ) | _BIT(IRQ_SUB2FIQ));

	// Interrupt on MIC?
	if (sts != 0)
	{
		// Find first active interrupt
		bit_pos = (INTERRUPT_SOURCE_T) findfirstbit(sts);
		intsrc = bit_pos;
		pIntc = pMIC;
	}
	else if (pSIC1->sr != 0)
	{
		// Find first active interrupt
		bit_pos = (INTERRUPT_SOURCE_T) findfirstbit(pSIC1->sr);
		intsrc = bit_pos + IRQ_SIC1_BASE;
		pIntc = pSIC1;
	}
	else if (pSIC2->sr != 0)
	{
		// Find first active interrupt
		bit_pos = (INTERRUPT_SOURCE_T) findfirstbit(pSIC2->sr);
		intsrc = bit_pos + IRQ_SIC2_BASE;
		pIntc = pSIC2;
	}
	else
	{
		// This should never happen
		return SYSINTR_NOP;
	}

	// Get BSP IRQ mapped to this hardware IRQ
	sts = lp32xxToBSPIRQ [intsrc];
	if ((sts == OAL_INTR_IRQ_UNDEFINED) && (intsrc != IRQ_DMA))
	{
		// Unmapped interrupt, disable interrupt
		pIntc->er &= ~_BIT(bit_pos);

		return SYSINTR_NOP;
	}

	// Is this the system timer interrupt?
    if (sts == OAL_INTR_IRQ_TICK)
    {
        sysIntr = OALTimerIntrHandler();
    }
#ifdef IMGPROFILFER
#if IMGPROFILFER==1
    else if (sts == OAL_INTR_IRQ_PROFILER)
    {
		// Disable profiler interrupt
		pIntc->er &= ~_BIT(bit_pos);

        // Call profiler interrupt
        if (g_pProfilerISR != NULL)
        {
            sysIntr = g_pProfilerISR(ra);
        }
    }
#endif
#endif
	else if (intsrc == IRQ_DMA)
    {
		// DMA interrupt requires remapping to a virtual channel
		// INTR value
		dma_get_int_ch(&dirq);
		IntrEnableVirtual((OAL_TO_HW_IRQ_T *) &lp32xx_ierqsupp[dirq], FALSE);
        sysIntr = OALIntrTranslateIrq(dirq);
	}
	else
	{
		// Mapped interrupt, return SYSINTR value for the interrupt
		sysIntr = OALIntrTranslateIrq(sts);

		// Disable interrupt
		pIntc->er &= ~_BIT(bit_pos);
	}

    return sysIntr;
}

//------------------------------------------------------------------------------
//
// OEMInterruptHandlerFIQ
//
// Stub function for ARM FIQ handler
//
void OEMInterruptHandlerFIQ()
{
}

⌨️ 快捷键说明

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