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

📄 intr.c

📁 6410BSP1
💻 C
📖 第 1 页 / 共 3 页
字号:
            uiMask = g_pGPIOReg->EINT0MASK;

            for (nNumber=4; nNumber<12; nNumber++)    // EINT4~EINT11
            {
                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_EINT4+(nNumber-4));            // Set Virtual IRQ
                    break;
                }
            }
        }
        else if (PhysicalIRQ == PHYIRQ_EINT2)
        {
            // Do not mask PHYIRQ_EINT2 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;
            uiMask = g_pGPIOReg->EINT0MASK;

            for (nNumber=12; nNumber<20; nNumber++)    // EINT12~EINT19
            {
                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_EINT12+(nNumber-12));        // Set Virtual IRQ
                    break;
                }
            }
        }
        else if (PhysicalIRQ == PHYIRQ_EINT3)
        {
            // Do not mask PHYIRQ_EINT3 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;
            uiMask = g_pGPIOReg->EINT0MASK;

            for (nNumber=20; nNumber<28; nNumber++)    // EINT20~EINT27
            {
                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_EINT20+(nNumber-20));        // Set Virtual IRQ
                    break;
                }
            }
        }
        else if (PhysicalIRQ == PHYIRQ_DMA0)
        {
            DWORD dwIntStatus;

#ifdef    VIC_MASK
            IntEnVIC1 &= ~(1<<(PHYIRQ_DMA0-VIC1_BIT_OFFSET));
#else
            g_pVIC1Reg->VICINTENCLEAR = (1<<(PHYIRQ_DMA0-VIC1_BIT_OFFSET));
#endif

            dwIntStatus = g_pDMAC0Reg->DMACIntStatus;

            if (dwIntStatus & 0x01) VirtualIRQ = IRQ_DMA0_CH0;        // channel 0
            else if (dwIntStatus & 0x02) VirtualIRQ = IRQ_DMA0_CH1;    // channel 1
            else if (dwIntStatus & 0x04) VirtualIRQ = IRQ_DMA0_CH2;    // channel 2
            else if (dwIntStatus & 0x08) VirtualIRQ = IRQ_DMA0_CH3;    // channel 3
            else if (dwIntStatus & 0x10) VirtualIRQ = IRQ_DMA0_CH4;    // channel 4
            else if (dwIntStatus & 0x20) VirtualIRQ = IRQ_DMA0_CH5;    // channel 5
            else if (dwIntStatus & 0x40) VirtualIRQ = IRQ_DMA0_CH6;    // channel 6
            else if (dwIntStatus & 0x80) VirtualIRQ = IRQ_DMA0_CH7;    // channel 7
        }
        else if (PhysicalIRQ == PHYIRQ_DMA1)
        {
            DWORD dwIntStatus;

#ifdef    VIC_MASK
            IntEnVIC1 &= ~(1<<(PHYIRQ_DMA1-VIC1_BIT_OFFSET));
#else
            g_pVIC1Reg->VICINTENCLEAR = (1<<(PHYIRQ_DMA1-VIC1_BIT_OFFSET));
#endif

            dwIntStatus = g_pDMAC1Reg->DMACIntStatus;

            if (dwIntStatus & 0x01) VirtualIRQ = IRQ_DMA1_CH0;        // channel 0
            else if (dwIntStatus & 0x02) VirtualIRQ = IRQ_DMA1_CH1;    // channel 1
            else if (dwIntStatus & 0x04) VirtualIRQ = IRQ_DMA1_CH2;    // channel 2
            else if (dwIntStatus & 0x08) VirtualIRQ = IRQ_DMA1_CH3;    // channel 3
            else if (dwIntStatus & 0x10) VirtualIRQ = IRQ_DMA1_CH4;    // channel 4
            else if (dwIntStatus & 0x20) VirtualIRQ = IRQ_DMA1_CH5;    // channel 5
            else if (dwIntStatus & 0x40) VirtualIRQ = IRQ_DMA1_CH6;    // channel 6
            else if (dwIntStatus & 0x80) VirtualIRQ = IRQ_DMA1_CH7;    // channel 7
        }
        else if (PhysicalIRQ < VIC1_BIT_OFFSET)
        {
#ifdef    VIC_MASK
            IntEnVIC0 &= ~(1<<PhysicalIRQ);
#else
            g_pVIC0Reg->VICINTENCLEAR = (1<<PhysicalIRQ);
#endif
        }
        else if (PhysicalIRQ < PHYIRQ_MAX_S3C6410)
        {
#ifdef    VIC_MASK
            IntEnVIC1 &= ~(1<<(PhysicalIRQ-VIC1_BIT_OFFSET));
#else
            g_pVIC1Reg->VICINTENCLEAR = (1<<(PhysicalIRQ-VIC1_BIT_OFFSET));
#endif
        }

        // We don't recommend using IRQ sharing and IISR.
        // To use static mapping from design time is recommended for device driver developer.
        // The IISR can affect whole system's performance
        // and it makes interrupt handling and debugging harder.
        
        // First find if IRQ is claimed by chain
        SysIntr = NKCallIntChain((BYTE)VirtualIRQ);

        if (SysIntr == SYSINTR_CHAIN || !NKIsSysIntrValid(SysIntr))
        {
            // IRQ wasn't claimed, use static mapping
            SysIntr = OALIntrTranslateIrq(VirtualIRQ);
        }
    }

    // Clear Vector Address Register
    g_pVIC0Reg->VICADDRESS = 0x0;
    g_pVIC1Reg->VICADDRESS = 0x0;

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

    return SysIntr;
}

static void PrepareEINTIntr(void)
{
    g_pGPIOReg->EINT0MASK = 0xFFFFFFFF;    // Mask All Sub Interrupts
    g_pGPIOReg->EINT0PEND = 0xFFFFFFFF;    // Clear All Sub Pending Interrupts

    g_pVIC0Reg->VICINTENABLE |= (0x1<<PHYIRQ_EINT0); // Enable IRQ_EINT0 ~ IRQ_EINT3
    g_pVIC0Reg->VICINTENABLE |= (0x1<<PHYIRQ_EINT1); // Enable // IRQ_EINT4 ~ IRQ_EINT11
    
    g_pVIC1Reg->VICINTENABLE |= (0x1<<(PHYIRQ_EINT2 - VIC1_BIT_OFFSET)); // Enable IRQ_EINT12 ~ IRQ_EINT19
    g_pVIC1Reg->VICINTENABLE |= (0x1<<(PHYIRQ_EINT3 - VIC1_BIT_OFFSET)); // Enable IRQ_EINT20 ~ IRQ_EINT27
}

static void PrepareDMACIntr(void)
{
    // Disable Interrupt of All Channel
    // Mask TC and Error Interrupt
    // Clear Interrupt Pending

    g_pDMAC0Reg->DMACC0Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC0Reg->DMACC0Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC0Reg->DMACC1Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC0Reg->DMACC1Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC0Reg->DMACC2Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC0Reg->DMACC2Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC0Reg->DMACC3Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC0Reg->DMACC3Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC0Reg->DMACC4Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC0Reg->DMACC4Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC0Reg->DMACC5Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC0Reg->DMACC5Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC0Reg->DMACC6Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC0Reg->DMACC6Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC0Reg->DMACC7Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC0Reg->DMACC7Configuration &= (3<<14);    // TCINT & ErrINT Mask

    g_pDMAC0Reg->DMACIntTCClear = 0xff;            // TC Int Pending Clear
    g_pDMAC0Reg->DMACIntErrClear = 0xff;            // Err Int Pending Clear

    g_pDMAC1Reg->DMACC0Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC1Reg->DMACC0Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC1Reg->DMACC1Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC1Reg->DMACC1Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC1Reg->DMACC2Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC1Reg->DMACC2Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC1Reg->DMACC3Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC1Reg->DMACC3Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC1Reg->DMACC4Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC1Reg->DMACC4Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC1Reg->DMACC5Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC1Reg->DMACC5Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC1Reg->DMACC6Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC1Reg->DMACC6Configuration &= (3<<14);    // TCINT & ErrINT Mask
    g_pDMAC1Reg->DMACC7Control0 &= ~(1<<31);        // TCINT Disable
    g_pDMAC1Reg->DMACC7Configuration &= (3<<14);    // TCINT & ErrINT Mask

    g_pDMAC1Reg->DMACIntTCClear = 0xff;            // TC Int Pending Clear
    g_pDMAC1Reg->DMACIntErrClear = 0xff;            // Err Int Pending Clear
}

static void InitializeVIC(void)
{
    // Disable All Interrupts
    g_pVIC0Reg->VICINTENCLEAR = 0xFFFFFFFF;
    g_pVIC1Reg->VICINTENCLEAR = 0xFFFFFFFF;
    g_pVIC0Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;
    g_pVIC1Reg->VICSOFTINTCLEAR = 0xFFFFFFFF;

    // Clear Current Active Vector Address
    g_pVIC0Reg->VICADDRESS = 0x0;
    g_pVIC1Reg->VICADDRESS = 0x0;

    // Initialize Vector Address Table
    VICTableInit();

    // Disable Vectored Interrupt Mode on CP15
    System_DisableVIC();

    // Enable IRQ Interrupt on CP15
    System_EnableIRQ();

    // Enable FIQ Interrupt on CP15
    System_EnableFIQ();
}

void VICTableInit(void)
{
    // This Function is reference by OEMPowerOff() in "Off.c"
    // Make Sure that Caller and This function is in Same Address Space

    // Fill Vector Address of VIC0
    // Actually, Filled with Physical IRQ Numbers.
    // Because We do not use vectored interrupt feature

    g_pVIC0Reg->VICVECTADDR0 = PHYIRQ_EINT0;
    g_pVIC0Reg->VICVECTADDR1 = PHYIRQ_EINT1;
    g_pVIC0Reg->VICVECTADDR2 = PHYIRQ_RTC_TIC;
    g_pVIC0Reg->VICVECTADDR3 = PHYIRQ_CAMIF_C;
    g_pVIC0Reg->VICVECTADDR4 = PHYIRQ_CAMIF_P;

    g_pVIC0Reg->VICVECTADDR5 = PHYIRQ_I2C1;
    g_pVIC0Reg->VICVECTADDR6 = PHYIRQ_I2S_V40;
    g_pVIC0Reg->VICVECTADDR7 = PHYIRQ_SSS;
    g_pVIC0Reg->VICVECTADDR8 = PHYIRQ_3D;
    
    g_pVIC0Reg->VICVECTADDR9 = PHYIRQ_POST;
    g_pVIC0Reg->VICVECTADDR10 = PHYIRQ_ROTATOR;
    g_pVIC0Reg->VICVECTADDR11 = PHYIRQ_2D;
    g_pVIC0Reg->VICVECTADDR12 = PHYIRQ_TVENC;
    g_pVIC0Reg->VICVECTADDR13 = PHYIRQ_TVSCALER;
    g_pVIC0Reg->VICVECTADDR14 = PHYIRQ_BATF;
    g_pVIC0Reg->VICVECTADDR15 = PHYIRQ_JPEG;
    g_pVIC0Reg->VICVECTADDR16 = PHYIRQ_MFC;
    g_pVIC0Reg->VICVECTADDR17 = PHYIRQ_SDMA0;
    g_pVIC0Reg->VICVECTADDR18 = PHYIRQ_SDMA1;
    g_pVIC0Reg->VICVECTADDR19 = PHYIRQ_ARM_DMAERR;
    g_pVIC0Reg->VICVECTADDR20 = PHYIRQ_ARM_DMA;
    g_pVIC0Reg->VICVECTADDR21 = PHYIRQ_ARM_DMAS;
    g_pVIC0Reg->VICVECTADDR22 = PHYIRQ_KEYPAD;
    g_pVIC0Reg->VICVECTADDR23 = PHYIRQ_TIMER0;
    g_pVIC0Reg->VICVECTADDR24 = PHYIRQ_TIMER1;
    g_pVIC0Reg->VICVECTADDR25 = PHYIRQ_TIMER2;
    g_pVIC0Reg->VICVECTADDR26 = PHYIRQ_WDT;
    g_pVIC0Reg->VICVECTADDR27 = PHYIRQ_TIMER3;
    g_pVIC0Reg->VICVECTADDR28 = PHYIRQ_TIMER4;
    g_pVIC0Reg->VICVECTADDR29 = PHYIRQ_LCD0_FIFO;
    g_pVIC0Reg->VICVECTADDR30 = PHYIRQ_LCD1_FRAME;
    g_pVIC0Reg->VICVECTADDR31 = PHYIRQ_LCD2_SYSIF;

    // Fill Vector Address of VIC1
    g_pVIC1Reg->VICVECTADDR0 = PHYIRQ_EINT2;
    g_pVIC1Reg->VICVECTADDR1 = PHYIRQ_EINT3;
    g_pVIC1Reg->VICVECTADDR2 = PHYIRQ_PCM0;
    g_pVIC1Reg->VICVECTADDR3 = PHYIRQ_PCM1;
    g_pVIC1Reg->VICVECTADDR4 = PHYIRQ_AC97;
    g_pVIC1Reg->VICVECTADDR5 = PHYIRQ_UART0;
    g_pVIC1Reg->VICVECTADDR6 = PHYIRQ_UART1;
    g_pVIC1Reg->VICVECTADDR7 = PHYIRQ_UART2;
    g_pVIC1Reg->VICVECTADDR8 = PHYIRQ_UART3;
    g_pVIC1Reg->VICVECTADDR9 = PHYIRQ_DMA0;
    g_pVIC1Reg->VICVECTADDR10 = PHYIRQ_DMA1;
    g_pVIC1Reg->VICVECTADDR11 = PHYIRQ_ONENAND0;
    g_pVIC1Reg->VICVECTADDR12 = PHYIRQ_ONENAND1;
    g_pVIC1Reg->VICVECTADDR13 = PHYIRQ_NFC;
    g_pVIC1Reg->VICVECTADDR14 = PHYIRQ_CFC;
    g_pVIC1Reg->VICVECTADDR15 = PHYIRQ_UHOST;
    g_pVIC1Reg->VICVECTADDR16 = PHYIRQ_SPI0;
    g_pVIC1Reg->VICVECTADDR17 = PHYIRQ_SPI1;
    g_pVIC1Reg->VICVECTADDR18 = PHYIRQ_I2C;
    g_pVIC1Reg->VICVECTADDR19 = PHYIRQ_HSITX;
    g_pVIC1Reg->VICVECTADDR20 = PHYIRQ_HSIRX;
    g_pVIC1Reg->VICVECTADDR21 = PHYIRQ_RESERVED;
    g_pVIC1Reg->VICVECTADDR22 = PHYIRQ_MSM;
    g_pVIC1Reg->VICVECTADDR23 = PHYIRQ_HOSTIF;
    g_pVIC1Reg->VICVECTADDR24 = PHYIRQ_HSMMC0;
    g_pVIC1Reg->VICVECTADDR25 = PHYIRQ_HSMMC1;
    g_pVIC1Reg->VICVECTADDR26 = PHYIRQ_OTG;
    g_pVIC1Reg->VICVECTADDR27 = PHYIRQ_IRDA;
    g_pVIC1Reg->VICVECTADDR28 = PHYIRQ_RTC_ALARM;
    g_pVIC1Reg->VICVECTADDR29 = PHYIRQ_SEC;
    g_pVIC1Reg->VICVECTADDR30 = PHYIRQ_PENDN;
    g_pVIC1Reg->VICVECTADDR31 = PHYIRQ_ADC;
}

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

⌨️ 快捷键说明

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