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

📄 interrupt.c

📁 Cirrus EP9315 wince bsp
💻 C
📖 第 1 页 / 共 2 页
字号:
            #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 + -