📄 intr.c
字号:
// 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 + -