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