📄 interrupt.c
字号:
#endif
}
}
else
{
//
// if we're timing interrupts, keep track of when this one came in
//
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
//
// Not profiling, update the millisecond counter
//
CurMSec += RESCHED_PERIOD;
#if (CE_MAJOR_VER == 0x0003)
DiffMSec += RESCHED_PERIOD;
#endif
dwIntrTimeCountdown--;
if (dwIntrTimeCountdown == 0)
{
dwIntrTimeCountdown = dwIntrTimeCountdownRef;
wNumInterrupts = 0;
dwIsrTime2 = PerfCountSinceTick();
retval = SYSINTR_TIMING;
}
else
{
#if (CE_MAJOR_VER == 0x0003)
if (ticksleft || (dwSleepMin && (dwSleepMin <= DiffMSec)) ||
(dwPreempt && (dwPreempt <= DiffMSec)))
#else
if ((int) (CurMSec - dwReschedTime) >= 0)
#endif
{
retval = SYSINTR_RESCHED;
}
}
}
else
{
//
// not profiling, update the millisecond counter
//
CurMSec += RESCHED_PERIOD;
#if (CE_MAJOR_VER == 0x0003)
DiffMSec += RESCHED_PERIOD;
#endif
#if (CE_MAJOR_VER == 0x0003)
if (ticksleft || (dwSleepMin && (dwSleepMin <= DiffMSec)) ||
(dwPreempt && (dwPreempt <= DiffMSec)))
#else
if ((int) (CurMSec - dwReschedTime) >= 0)
#endif
{
retval = SYSINTR_RESCHED;
}
}
}
return retval;
}
//****************************************************************************
// SysIntrNumToInterruptMask
//****************************************************************************
// Converts a System interrupt number to the bits used in the interrupt mask.
//
//
BOOL SysIntrNumToInterruptMask
(
DWORD dwSysIntr,
PULONG pulInterruptMask1,
PULONG pulInterruptMask2
)
{
BOOL bRet = TRUE;
switch(dwSysIntr)
{
case SYSINTR_TIMING:
//
// No action necessary. Needs to be handled in the calling routine.
//
*pulInterruptMask1 = 0;
*pulInterruptMask2 = 0;
break;
case SYSINTR_ETHER:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_ETHERNET;
break;
case SYSINTR_USB:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_USB;
break;
case SYSINTR_UART1:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_UART1;
break;
case SYSINTR_UART2:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_UART2;
break;
case SYSINTR_UART3:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_UART3;
break;
case SYSINTR_KEYBOARD:
*pulInterruptMask1 = INT1_KEYPAD;
*pulInterruptMask2 = 0;
break;
case SYSINTR_SPI:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_SPI;
break;
case SYSINTR_RTC_ALARM:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_RTC;
break;
case SYSINTR_DMA0:
case SYSINTR_DMA1:
case SYSINTR_DMA2:
case SYSINTR_DMA3:
case SYSINTR_DMA4:
case SYSINTR_DMA5:
case SYSINTR_DMA6:
case SYSINTR_DMA7:
case SYSINTR_DMA8:
case SYSINTR_DMA9:
*pulInterruptMask1 = INT1_DMAM2P0<< (dwSysIntr - SYSINTR_DMA0);
*pulInterruptMask2 = 0;
break;
case SYSINTR_TOUCH:
*pulInterruptMask1 = INT1_TOUCH;
*pulInterruptMask2 = 0;
break;
case SYSINTR_TIMER2:
*pulInterruptMask1 = INT1_TIMER2;
*pulInterruptMask2 = 0;
break;
case SYSINTR_IR:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_IRDA;
break;
case SYSINTR_IDE:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_EXT3;
break;
case SYSINTR_PCMCIA_LEVEL:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_PCMCIA_IRQ;
break;
case SYSINTR_PCMCIA_STATE:
*pulInterruptMask1 = INT1_PCMCIA_CD1 | INT1_PCMCIA_CD2 | INT1_PCMCIA_BVD1;
*pulInterruptMask2 = INT2_PCMCIA_BVD2;
break;
default:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = 0;
bRet = FALSE;
break;
}
return bRet;
}
/*
* @func BOOL | OEMInterruptEnable | Enable a hardware interrupt
*
* @parms
* idInt Interrupt ID to be enabled.
* See Interrupt ID's.Interrupt ID's> for a list of
* possble values.
*
* pvData ptr to data passed in in the InterruptInitialize() call
*
* cbData Size of data pointed to by pvData
*
* @rdesc Returns TRUE if valid interrupt ID or FALSE if invalid ID.
*
* @comm This function is called by the Kernel when a device driver
* calls InterruptInitialize(). The system is not preemptible
* when this function is called.
*
* @xref
* Overview.Windows CE Kernel OEM Interface
* InterruptInitialize
*/
BOOL OEMInterruptEnable(DWORD idInt, LPVOID pvData, DWORD cbData)
{
BOOL bRet = TRUE;
ULONG ulIntMask1, ulIntMask2;
bRet = SysIntrNumToInterruptMask(idInt, &ulIntMask1, &ulIntMask2);
INTERRUPTS_OFF();
if(ulIntMask1)
{
*VIC1_INTENABLE = ulIntMask1;
gdwInterruptMask1 |= ulIntMask1;
}
if(ulIntMask2)
{
*VIC2_INTENABLE = ulIntMask2;
gdwInterruptMask2 |= ulIntMask2;
}
if(idInt ==SYSINTR_SPI)
{
fPS2Int = 0;
}
INTERRUPTS_ON();
return(bRet);
}
/*
* @func BOOL | OEMInterruptDisable | Disable a hardware interrupt
*
* @rdesc none
*
* @parms
* idInt Interrupt ID to be disabled.
* See Interrupt ID's.Interrupt ID's> for a list of
* possble values.
*
* @comm OEMInterruptDisable is called by the Kernel when a device driver
* calls <f InterruptDisable>. The system is not preemtible when this
* function is called.
*
* @xref
* Overview.Windows CE Kernel OEM Interface
* InterruptDisable
*/
void OEMInterruptDisable(DWORD idInt)
{
// NKDbgPrintfW(L"OEMInterruptDisable: Interrupt #%02d\r\n", idInt);
BOOL bRet = TRUE;
ULONG ulIntMask1, ulIntMask2;
bRet = SysIntrNumToInterruptMask(idInt, &ulIntMask1, &ulIntMask2);
INTERRUPTS_OFF();
if(ulIntMask1)
{
*VIC1_INTCLEAR = ulIntMask1;
gdwInterruptMask1 &= ~ulIntMask1;
}
if(ulIntMask2)
{
*VIC2_INTCLEAR = ulIntMask2;
gdwInterruptMask2 &= ~ulIntMask2;
}
INTERRUPTS_ON();
return;
}
/*
* @func BOOL | OEMInterruptDone | Signal completion of interrupt processing
*
* @rdesc none
*
* @parms
* idInt Interrupt ID to be enabled.
* See Interrupt ID's.Interrupt ID's> for a list of
* possble values.
*
* @comm OEMInterruptDone is called by the Kernel when a device driver
* calls InterruptDone(). The system is not preemtible when this
* function is called.
*
* @xref
* Overview.Kernel Interrupt Support
* InterruptDone
*/
void OEMInterruptDone(DWORD idInt)
{
BOOL bRet = TRUE;
ULONG ulIntMask1, ulIntMask2;
bRet = SysIntrNumToInterruptMask(idInt, &ulIntMask1, &ulIntMask2);
INTERRUPTS_OFF();
// NOTE: we expect the interrupt to be turned off at the device. The
// state isn't latched in any board-level registers.
// Enable interrupt.
//OEMInterruptEnable(idInt, NULL, 0);
if(ulIntMask1)
{
*VIC1_INTENABLE = ulIntMask1;
// ASSERT(gdwInterruptMask1 & ulIntMask1);
}
if(ulIntMask2)
{
*VIC2_INTENABLE = ulIntMask2;
// ASSERT(gdwInterruptMask2 & ulIntMask2);
}
INTERRUPTS_ON();
}
//****************************************************************************
// OEMInitInterrupts
//****************************************************************************
// Initialize the interrupt controller.
//
//
void OEMInitInterrupts(void )
{
//
// Currently, interrupts on generate irq. No FIQ's are generated.
//
*VIC1_INTSELECT = 0;
*VIC2_INTSELECT = 0;
//
// Only the timer interrupt will be enabled initially.
//
*VIC1_INTCLEAR = 0xFFFFFFFF;
*VIC2_INTCLEAR = 0xFFFFFFFF;
//
// Clear all software interrupts.
//
*VIC1_SOFTINTCLEAR = 0xFFFFFFFF;
*VIC2_SOFTINTCLEAR = 0xFFFFFFFF;
//
// Allow the Vic to be programmed in all modes.
//
*VIC1_PROTECTION = 0;
*VIC2_PROTECTION = 0;
//
// Even though we are not using the vectored part of the vectored interrupt
// controller, we must write VECTCURADDR in order to make sure that lower
// priority interrupts occur.
//
// If you don't do these write no interrupts may occur.
//
*VIC1_VECTCURADDR = 0;
*VIC2_VECTCURADDR = 0;
//
// Enable the timer interrupt.
//
*VIC1_INTENABLE = INT1_TIMER1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -