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