📄 interrupt.c
字号:
}
// ulVic1Last = ulVic1Irq;
// ulVic2Last = ulVic2Irq;
//
// If we get any device interrupts, signal the resume flag. The flag
// will release the CPU from OEMPowerOff if the user had previously
// chosen to suspend the platform. In OEMPowerOff, only the interrupts
// allowed to wake us up will be enabled so we needn't worry about
// that here.
//
if(retval < SYSINTR_MAXIMUM && (!gfResumeFlag) )
{
if( gfSysIntrWakeupMask[retval] )
{
//RETAILMSG(1, (TEXT("resume %x\r\n"),retval));
gfResumeFlag = TRUE;
gdwLastWakeupSource = retval;
}
}
if( retval !=SYSINTR_NOP )
fInterruptFlag = TRUE;
g_dwLastInterrupt= retval;
return retval;
}
//****************************************************************************
// TimerInterrupt
//****************************************************************************
// Lets put all of the timer interrupt handling in one place.
// This code was taken from the arm integrator platform.
// The code is confusing, so I cleaned it up a little bit by making one
// ending point.
//
int TimerInterrupt(void)
{
DWORD retval = SYSINTR_NOP;
DWORD dwTimerVal;
static DWORD dwLastTimerValue=0;
static BOOL bFirstTime=TRUE;
extern volatile DWORD PerfCountValueSinceTick;
extern void SetSysTimerInterval(DWORD dwTicks);
// static int iCount = 0;
//
// update the tick count
//
if( bFirstTime )
{
CurTicks.QuadPart=(CurMSec+RESCHED_PERIOD)*983;
dwLastTimerValue=*TIM_DEBUGVALUELOW;
bFirstTime=FALSE;
}
else
{
dwTimerVal=*TIM_DEBUGVALUELOW;
if( (int)(dwTimerVal-dwLastTimerValue)<0 )
CurTicks.QuadPart += dwTimerVal + (0xFFFFFFFF - dwLastTimerValue);
else
CurTicks.QuadPart += dwTimerVal-dwLastTimerValue;
dwLastTimerValue=dwTimerVal;
}
//CurTicks.QuadPart = CurTicksCount.QuadPart*508468/983040;// dwReschedIncrement;
//
// Print out a 1 every second. I want to make sure that we are getting ticks.
//
// Call the profile ISR if it's enabled.
//
if (PProfileInterrupt)
{
retval = PProfileInterrupt();
if(retval == SYSINTR_RESCHED)
{
//
// Update the millisecond counter
//
CurMSec += RESCHED_PERIOD;
}
}
else
{
//
// if we're timing interrupts, keep track of when this one came in
//
static DWORD dwLastCount= 0;
if( (int)( dwLastCount- *TIM_TIMER3VALUE ) >800 )
{
RETAILMSG(1, (TEXT("INT lost %d last %d \r\n"), dwLastCount- *TIM_TIMER3VALUE ,g_dwLastInterrupt ));
}
dwLastCount=*TIM_TIMER3VALUE;
CurMSec += RESCHED_PERIOD;
PerfCountValueSinceTick+=RESCHED_INCREMENT;
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
RETAILMSG(1, (TEXT("IntrTimer\r\n") ));
//
// Not profiling, update the millisecond counter
//
dwIntrTimeCountdown--;
if (dwIntrTimeCountdown == 0)
{
dwIntrTimeCountdown = dwIntrTimeCountdownRef;
wNumInterrupts = 0;
dwIsrTime2 = PerfCountSinceTick();
retval = SYSINTR_TIMING;
}
else
{
if ((int) (CurMSec - dwReschedTime) >= 0)
{
retval = SYSINTR_RESCHED;
}
}
}
else
{
//
// not profiling, update the millisecond counter
//
//CurMSec = dwReschedTime;
if ((int) (CurMSec - dwReschedTime) >= 0)
{
PerfCountValueSinceTick=0;
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;
/*
#ifdef EDB9315A_CIR
case SYSINTR_PIO_CIR:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_GPIO;
break;
#else
case SYSINTR_IR:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_IRDA;
break;
#endif
*/
case SYSINTR_GPIO:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_GPIO;
break;
case SYSINTR_CAN1:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_GPIO;
break;
case SYSINTR_CAN2:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_GPIO;
break;
case SYSINTR_IDE:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_EXT3;
break;
#ifdef EP93XX_SIMULAT_PS2_KBD
case SYSINTR_PS2_PORT:
//RETAILMSG(1, (TEXT("SYSINTR_PS2_PORT\r\n")));
*pulInterruptMask1 = 0;
*pulInterruptMask2 = 0; // the PS2 KeyBoard driver only see a pseudo interrupt. so don't care the interrupt.
break;
#endif
#ifdef EP93XX_SD_MMC
case SYSINTR_CARD_RESPONSE:
//RETAILMSG(1,(L"SD_MMC response done\n"));
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_EXT1;
break;
case SYSINTR_CARD_DETECT:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_EXT1;
break;
#elif EP93XX_MS_CARD
case SYSINTR_CARD_RESPONSE:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_EXT2;
break;
case SYSINTR_CARD_DETECT:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_EXT2;
break;
#endif
#ifdef EP93XX_USB_SLAVE
case SYSINTR_USBSLAVE:
//RETAILMSG(1, (TEXT("SYSINTR_PS2_PORT\r\n")));
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_EXT0; // the PS2 KeyBoard driver only see a pseudo interrupt. so don't care the interrupt.
break;
#endif
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;
case SYSINTR_DMA_M2M0:
*pulInterruptMask1 = INT1_DMAM2M0;
*pulInterruptMask2 = 0;
break;
case SYSINTR_DMA_M2M1:
*pulInterruptMask1 = INT1_DMAM2M1;
*pulInterruptMask2 = 0;
break;
case SYSINTR_PIO_PLAYBACK:
*pulInterruptMask1 = INT1_UNUSED1;
*pulInterruptMask2 = 0;
break;
case SYSINTR_PIO_RECORD:
*pulInterruptMask1 = INT1_UNUSED2;
*pulInterruptMask2 = 0;
break;
//#ifdef BSP_EXT_UART
case SYSINTR_UART4:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_GPIO;
//RETAILMSG(1, (TEXT("SysIntrNumToInterruptMask,*pulInterruptMask1 = 0x%X,*pulInterruptMask2 = 0x%X.\r\n"),*pulInterruptMask1,*pulInterruptMask2));
break;
case SYSINTR_UART5:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_GPIO;
break;
case SYSINTR_UART6:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_GPIO;
break;
case SYSINTR_UART7:
*pulInterruptMask1 = 0;
*pulInterruptMask2 = INT2_GPIO;
break;
//#endif
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;
}
if((idInt == SYSINTR_PIO_PLAYBACK) && (cbData == sizeof(PIOBufferParameters)) )
{
PIOBufferParameters *pPIO = (PIOBufferParameters *)pvData;
sPlayBack.pulPosition = sPlayBack.pulBuffer = pPIO->pulBuffer = gulTransmitBuffer;
sPlayBack.ulBufferSize = pPIO->ulBufferSize;
sPlayBack.pulBufferEnd = sPlayBack.pulBuffer + (sPlayBack.ulBufferSize>>2);
sPlayBack.pulBufferHalf = sPlayBack.pulBuffer + (sPlayBack.ulBufferSize>>3);
sPlayBack.bEnabled = FALSE;
sPlayBack.bIntEnabled = TRUE;
gbAC97 = pPIO->bAC97;
if(!sRecord.bIntEnabled )
{
if(pPIO->bAC97)
{
gdwInterruptMask1 |= INT1_AAC;
*VIC1_INTSELECT |= INT1_AAC;
*VIC1_INTENABLE = INT1_AAC;
}
else
{
gdwInterruptMask2 |= INT2_SAI;
*VIC2_INTSELECT |= INT2_SAI;
*VIC2_INTENABLE = INT2_SAI;
}
}
}
if((idInt == SYSINTR_PIO_RECORD) && (cbData == sizeof(PIOBufferParameters)) )
{
PIOBufferParameters *pPIO = (PIOBufferParameters *)pvData;
sRecord.pulPosition = sRecord.pulBuffer = pPIO->pulBuffer = gulRecieveBuffer;
sRecord.ulBufferSize = pPIO->ulBufferSize;
sRecord.pulBufferEnd = sRecord.pulBuffer + (sRecord.ulBufferSize>>2);
sRecord.pulBufferHalf = sRecord.pulBuffer + (sRecord.ulBufferSize>>3);
sRecord.bEnabled = FALSE;
sRecord.bIntEnabled = TRUE;
gbAC97 = pPIO->bAC97;
if(!sPlayBack.bIntEnabled)
{
if(pPIO->bAC97)
{
gdwInterruptMask1 |= INT1_AAC;
*VIC1_INTSELECT |= INT1_AAC;
*VIC1_INTENABLE = INT1_AAC;
}
else
{
gdwInterruptMask2 |= INT2_SAI;
*VIC2_INTSELECT |= INT2_SAI;
*VIC2_INTENABLE = INT2_SAI;
}
}
}
#ifdef EP93XX_SIMULAT_PS2_KBD
if( idInt == SYSINTR_PS2_PORT ) //Initialize KeyBoard when driver calls InterruptInitialize( )
{
int init_edb931xPS2(void);
*VIC2_INTENABLE = INT2_EXT0;
gdwInterruptMask2 |= INT2_EXT0;
init_edb931xPS2( );
}
#endif
/*
#ifdef EDB9315A_CIR
if( idInt == SYSINTR_PIO_CIR )
{
// Enable EGPIO13 for CIR interrupt.
UINT value;
//OEMWriteDebugByte('E');
//OEMWriteDebugByte('\r');
//OEMWriteDebugByte('\n');
gnWi = 0;
gnKeyCode = 0;
value = *GPIO_PBDDR;
value &= ~0x20;
*GPIO_PBDDR = value; // Set port B as input
value = *GPIO_BINTEN;
value &= ~0x20;
*GPIO_BINTEN = value; // Disable all interrupt.
*GPIO_BEOI = 0x20; // Clean all previous interrupt
value = *GPIO_BINTTYPE1;
value |= 0x20; // edge trigure.
*GPIO_BINTTYPE1 = value;
value = *GPIO_BINTTYPE2;
value &= ~0x20; // Falling edge
*GPIO_BINTTYPE2 = value;
value = *GPIO_BINTEN;
value |= 0x20; // Enable interrupt
*GPIO_BINTEN = value;
}
#endif
*/
//#ifdef BSP_EXT_UART
if( idInt == SYSINTR_UART4)
{
// Enable EGPIO10 for UART4 interrupt.
UINT value;
value = *GPIO_PBDDR;
value &= ~EGPIO_UART4_INT;
*GPIO_PBDDR = value; // Set as input
value = *GPIO_BINTEN;
value &= ~EGPIO_UART4_INT;
*GPIO_BINTEN = value; // Disable interrupt.
value = *GPIO_BINTTYPE1;
//value &= ~EGPIO_UART4_INT; // level trigure.
value |= EGPIO_UART4_INT;
*GPIO_BINTTYPE1 = value;
value = *GPIO_BINTTYPE2;
value |= EGPIO_UART4_INT; // high level
*GPIO_BINTTYPE2 = value;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -