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

📄 interrupt.c

📁 ARM下加一个硬件驱动比较复杂
💻 C
📖 第 1 页 / 共 3 页
字号:


#ifdef   EP931X_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  EP931X_MS_CARD

	 case SYSINTR_CARD_RESPONSE:

	      *pulInterruptMask1  = 0;
            *pulInterruptMask2  = INT2_EXT2;
            break;

	 case SYSINTR_CARD_DETECT:
            *pulInterruptMask1  = 0;
            *pulInterruptMask2  = INT2_EXT2;
            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;
//-------------------------------------------------
//added by cyx 2005 06 08
#ifdef SBS_SAM3210            
        case SYSINTR_OEMUART1:
        case SYSINTR_OEMUART2:
        case SYSINTR_OEMUART3:	
        case SYSINTR_OEMUART4:	
            *pulInterruptMask1  = 0;
            *pulInterruptMask2  = INT2_EXT1;
         	break;
#endif
 //-----------------------------------------------
//-------------------------------------------------
//added by cyx 2005 06 08
#ifdef SBS_SBS04A03                    
        case SYSINTR_OEMUART1:
            *pulInterruptMask1  = 0;
            *pulInterruptMask2  = INT2_EXT0;
         	break;
 #endif
 //-----------------------------------------------
 //-----------------------------------------------
 //added by cyx 2005 09 08
 #ifdef BSP_USB_DEVICE
 	case SYSINTR_USB_CLIENT:
 		*pulInterruptMask1  = 0;
            	*pulInterruptMask2  = INT2_EXT2;	
 		break;
 #endif
 
//added by 许中
		case SYSINTR_CAN1:
		case SYSINTR_CAN2:
			*pulInterruptMask1  = 0;
            *pulInterruptMask2  = INT2_GPIO;

		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;

    
    int irqnum=0;
    bRet = SysIntrNumToInterruptMask(idInt, &ulIntMask1, &ulIntMask2);
    //-------------------------------------------------------------- 
    //added by cyx 2005 06 21	
   if(bRet){
   		 irqnum=GetIrqNum(ulIntMask1, ulIntMask2);
   		 if(irqnum)  InterlockedIncrement(&(EnableInterruptCount[irqnum]));
   }
   //---------------------------------------------------------------
   
    INTERRUPTS_OFF();


    if(ulIntMask1)
    {
        //----------------------------------------
        //added by cyx 2005 06 21
        if(irqnum){
        	if(EnableInterruptCount[irqnum]>0){
        		*VIC1_INTENABLE     = ulIntMask1;
        		gdwInterruptMask1   |= ulIntMask1;	
        	}
        }
        else
        //----------------------------------------
        {
        	*VIC1_INTENABLE     = ulIntMask1;
        	gdwInterruptMask1   |= ulIntMask1;
        }
   }

    if(ulIntMask2)
    {
	//----------------------------------------
        //added by cyx 2005 06 21
        if(irqnum){
        	if(EnableInterruptCount[irqnum]>0){
        		*VIC2_INTENABLE     = ulIntMask2;
        		gdwInterruptMask2   |= ulIntMask2;	
        	}
        }
        else
        //----------------------------------------
        {
        	*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 EP931X_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

    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;
	int irqnum=0;

    bRet = SysIntrNumToInterruptMask(idInt, &ulIntMask1, &ulIntMask2);
    //-------------------------------------------------------------- 
    //added by cyx 2005 06 21
    
    bRet = SysIntrNumToInterruptMask(idInt, &ulIntMask1, &ulIntMask2);
   if(bRet){
   		 irqnum=GetIrqNum(ulIntMask1, ulIntMask2);
   		 if(irqnum)  InterlockedDecrement(&(EnableInterruptCount[irqnum]));
   }
   //---------------------------------------------------------------
   
    INTERRUPTS_OFF();

    if(ulIntMask1)
    {
	//----------------------------------------
        //added by cyx 2005 06 21
        if(irqnum){
        	if(EnableInterruptCount[irqnum]==0){
        		*VIC1_INTCLEAR      = ulIntMask1;
        		gdwInterruptMask1   &= ~ulIntMask1;	
        	}
        }
        else
        //----------------------------------------
        {
        	*VIC1_INTCLEAR      = ulIntMask1;
        	gdwInterruptMask1   &= ~ulIntMask1;
        }
    }

    if(ulIntMask2)
    {
	//----------------------------------------
        //added by cyx 2005 06 21
        if(irqnum){
        	if(EnableInterruptCount[irqnum]==0){
        		*VIC2_INTCLEAR     = ulIntMask2;
        		gdwInterruptMask2  &= ~ulIntMask2;	
        	}
        }
        else
        //----------------------------------------
        {
        	*VIC2_INTCLEAR     = ulIntMask2;
        	gdwInterruptMask2  &= ~ulIntMask2;
        }
    }

    if(idInt == SYSINTR_PIO_PLAYBACK )
    {
        if(!sRecord.bIntEnabled)
        {
            if(gbAC97)
            {
                *VIC1_INTCLEAR          = INT1_AAC;
                gdwInterruptMask1       &= ~INT1_AAC;
            }
            else
            {
                *VIC2_INTCLEAR          = INT2_SAI;
                gdwInterruptMask2       &= ~INT2_SAI;
            }
        }
        sPlayBack.bEnabled      = FALSE;
        sPlayBack.bIntEnabled   = FALSE;
    }

    if(idInt == SYSINTR_PIO_RECORD )
    {
        if(!sPlayBack.bIntEnabled)
        {
            if(gbAC97)
            {
                *VIC1_INTCLEAR          = INT1_AAC;
                gdwInterruptMask1       &= ~INT1_AAC;
            }
            else
            {
                *VIC2_INTCLEAR          = INT2_SAI;
                gdwInterruptMask2       &= ~INT2_SAI;
            }
        }
        sRecord.bEnabled        = FALSE;
        sRecord.bIntEnabled     = FALSE;
    }


    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(idInt == SYSINTR_PIO_PLAYBACK )
    {
        *VIC1_SOFTINTCLEAR  = INT1_UNUSED1;

    }
    if(idInt == SYSINTR_PIO_RECORD )
    {
        *VIC1_SOFTINTCLEAR  = INT1_UNUSED2;

    }
    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 )
{

    //-------------------------------------------------
    //added by cyx 2005 06 20
    int i;
    for (i=0;i<100;i++)
    	EnableInterruptCount[i]=0;
    //-------------------------------------------------
    
    //
    // 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;


    //
    // Initialize the PIO Audio Variables to zero.
    //
    sPlayBack.pulBuffer     = (PULONG)gulTransmitBuffer;
    sPlayBack.ulBufferSize  = 0;
    sPlayBack.pulBufferEnd  = 0;
    sPlayBack.pulBufferHalf = 0;
    sPlayBack.pulPosition   = 0;
    sPlayBack.bEnabled      = FALSE;
    sPlayBack.bIntEnabled   = FALSE;


    sRecord.pulBuffer       = (PULONG)gulRecieveBuffer;
    sRecord.ulBufferSize    = 0;
    sRecord.pulBufferEnd    = 0;
    sRecord.pulBufferHalf   = 0;
    sRecord.pulPosition     = 0;
    sRecord.bEnabled        = FALSE;
    sRecord.bIntEnabled     = FALSE;

    gbAC97                  = FALSE;
}

⌨️ 快捷键说明

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