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

📄 interrupt.c

📁 ebd9307开发板wince bsp源码,包括cs8900,lcd,nand,serial,touch,usb,gpio,wd等驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
//**********************************************************************
//                                                                      
// Filename: interrupt.c
//                                                                      
// Description: OEM Interrupt handler.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to 
// use this source code. For a copy of the EULA, please see the 
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved                       
//                                                                      
//**********************************************************************
#include <windows.h>
#include <nkintr.h>
#include <oalintr.h>
#include <bldver.h> // Needed for CE_MAJOR_VER.
#include <drv_glob.h>
#include <hwdefs.h>
#include <clocks.h>
#include <audiopio.h>

//#define RETAILMSG DEBUGMSG
static DWORD g_dwLastInterrupt=0;

/*
#ifdef EDB9315A_CIR
#include <winbase.h>
// For DS6310 TV URC only
#define gnKeyIntCnt 26
const int gnMinInterval = 300; // 0.3ms
const int gnMaxInterval = 2600; // 2.6ms
LARGE_INTEGER gulIntTime[gnKeyIntCnt]; // Assume no more than 50 pulse for one key pressing.
int  gnIntDif[gnKeyIntCnt]; // gpio input level
int gnWi; // write index
UINT  gnKeyCode;
PUCHAR gstrKeyName;
static unsigned int gnKeyTable[10] = {
	0x1410100, //0b1010000010000000100000000,
	0x1000100, //0b1000000000000000100000000,
	0x1400100, //0b1010000000000000100000000,
	0x1100100, //0b1000100000000000100000000,
	0x1500100, //0b1010100000000000100000000,
	0x1040100, //0b1000001000000000100000000,
	0x1440100, //0b1010001000000000100000000,
	0x1140100, //0b1000101000000000100000000,
	0x1540100, //0b1010101000000000100000000,
	0x1010100 //0b1000000010000000100000000	
};
static UCHAR gstrKeyNameTable[11][10] = {
	"0",
	"1",
	"2",
	"3",
	"4",
	"5",
	"6",
	"7",
	"8",
	"9",
	"Unknown"
};

extern BOOL OEMQueryPerformanceCounter( LARGE_INTEGER *lpliPerformanceCount );

#endif
*/

extern DWORD dwReschedTime;

#define DEBUG_ALARM         0

volatile BOOL           gfRTCAlarm=FALSE;
volatile LARGE_INTEGER  gliRTCAlarmTicks;

volatile BOOL fInterruptFlag;
volatile DWORD gdwInterruptMask1=INT1_TIMER1, gdwInterruptMask2=0;
volatile DWORD  gdwInterruptWakeMask1, gdwInterruptWakeMask2;
volatile BOOL fPS2Int;
 volatile BYTE  gfSysIntrWakeupMask[SYSINTR_MAXIMUM];
volatile BOOL   gfResumeFlag=TRUE;
volatile DWORD  gdwLastWakeupSource;

volatile DWORD dwTimeValueWhenSuspend;

extern DWORD CurMSec;
extern volatile LARGE_INTEGER CurTicks;
extern DWORD dwReschedIncrement;
extern int (*PProfileInterrupt)(void);
extern DWORD dwIsrTime1, dwIsrTime2;
extern BOOL fIntrTime;
extern WORD wNumInterrupts;    // Reset by a read of the ISR times from the IST
extern DWORD dwIntrTimeCountdown;
extern DWORD dwIntrTimeCountdownRef;



//
// Function prototypes.
//
DWORD   PerfCountSinceTick(void);
int     TimerInterrupt(void);
DWORD   OEMTranslateIrq(DWORD Irq);
BOOL CPUClearSysTimerIRQ(void);
// ULONG   ulVic1Last, ulVic2Last;

struct AudioPIO     sPlayBack;
struct AudioPIO     sRecord;
BOOL    gbAC97;
ULONG gulTransmitBuffer[MAX_TRANSMIT_BUFFER_SIZE>>2];
ULONG gulRecieveBuffer[MAX_TRANSMIT_BUFFER_SIZE>>2];

#define     AC97CH              AC97I_CH1_BASE
/*
void delay (void) 
{ 
unsigned int i; 
for (i=1000000000;i>0;i--) 
; 
} 
*/

//****************************************************************************
// OEMInterruptHandlerFIQ
//****************************************************************************
// Used for PIO Audio instead of using a DMA channel.
// 
// On the EP93XX Rev D1 and E0 the following may cause audio glitches.
//
// 1.  Boot in 16 Bit mode
// 2.  Use USB
// 3.  Use DMA
//
// To work around this problem we use the FIQ handler to perform PIO audio.
//
void OEMInterruptHandlerFIQ()
{
    volatile register  ULONG ulTemp;
    register    ULONG   *p;


    // Fake CPUEnterIdle needs to know about interrupt firing.
    fInterruptFlag = TRUE;

    if(gbAC97)
    {
        //register    ULONG   ulAC97Status;
        register    ULONG   ulAC97ISR;
        register    ULONG   *pAC97DR = (ULONG   *)AC97CH+(AC97I_DR>>2);

        // ulAC97Status = AC97CH[AC97I_SR>>2];
        ulAC97ISR = AC97CH[AC97I_ISR>>2];
        if(ulAC97ISR & ISR_TIS)
        {
            //
            // Check to see if the transmit buffer is enabled.
            //
            if(sPlayBack.bEnabled )
            {
                
                p = sPlayBack.pulPosition;
                if(p == sPlayBack.pulBufferHalf)
                {
                    *VIC1_SOFTINT           = INT1_UNUSED1;
                }
                else if(p >= sPlayBack.pulBufferEnd )
                {
                    p = sPlayBack.pulPosition = sPlayBack.pulBuffer;
                    *VIC1_SOFTINT           = INT1_UNUSED1;
                }    

                *pAC97DR = *p++;
                *pAC97DR = *p++;
                *pAC97DR = *p++;
                *pAC97DR = *p++;

                sPlayBack.pulPosition = p;
            }
            else
            {
                *pAC97DR = 0;
                *pAC97DR = 0;
                *pAC97DR = 0;
                *pAC97DR = 0;
            }
        }

        //if(ulAC97Status & SR_RXFF)
        if(ulAC97ISR & ISR_RIS)
        {
            //
            // Check to see if the recieve buffer is enabled.
            //
            if(sRecord.bEnabled )
            {
                p = sRecord.pulPosition;
                if(p == sRecord.pulBufferHalf)
                {
                    *VIC1_SOFTINT           = INT1_UNUSED2;
                }
                else if(p >= sRecord.pulBufferEnd )
                {
                    p = sRecord.pulPosition = sRecord.pulBuffer;
                    *VIC1_SOFTINT           = INT1_UNUSED2;
                }    

                *p++ = *pAC97DR;
                *p++ = *pAC97DR;
                *p++ = *pAC97DR;
                *p++ = *pAC97DR;

                sRecord.pulPosition= p;
            }
            else
            {
                ulTemp = *pAC97DR;
                ulTemp = *pAC97DR;
                ulTemp = *pAC97DR;
                ulTemp = *pAC97DR;
            }
        }
    }
    else
    {
        register    ULONG   ulSAIStatus;

		DWORD	dwFillCount=0;
        //
        // Check to see if the Transmit Fifo is emtpy.
        //
        ulSAIStatus = *SAI_GSR;
		

        if(ulSAIStatus & GSR_TX0_FIFO_EMPTY )
			dwFillCount=8;
		else if(ulSAIStatus & GSR_TX0_FIFO_HALF_EMPTY )
			dwFillCount=4;

		if( dwFillCount )
        {
            //
            // Check to see if the transmit buffer is enabled.
            //
            if(sPlayBack.bEnabled )
            {
                p = sPlayBack.pulPosition;
                if(p == sPlayBack.pulBufferHalf)
                {
                    *VIC1_SOFTINT           = INT1_UNUSED1;
                }
                else if(p >= sPlayBack.pulBufferEnd )
                {
                    p = sPlayBack.pulPosition = sPlayBack.pulBuffer;
                    *VIC1_SOFTINT           = INT1_UNUSED1;
                }    

				while ( dwFillCount -- )
				{
					*SAI_TX0_LEFT  = *p++;
					*SAI_TX0_RIGHT = *p++;
				}
                sPlayBack.pulPosition= p;
            } 
            else
            {
				while ( dwFillCount -- )
				{
					*SAI_TX0_LEFT  = 0;
					*SAI_TX0_RIGHT = 0;
				}
            }
        }

		dwFillCount=0;
        if(ulSAIStatus & GSR_RX0_FIFO_FULL )
			dwFillCount=8;
		else if(ulSAIStatus & GSR_RX0_FIFO_HALF_FULL )
			dwFillCount=4;

		if( dwFillCount )
        {
            //
            // Check to see if the recieve buffer is enabled.
            //
            if(sRecord.bEnabled )
            {
                p = sRecord.pulPosition;
                if(p == sRecord.pulBufferHalf)
                {
                    *VIC1_SOFTINT           = INT1_UNUSED2;
                }
                else if(p >= sRecord.pulBufferEnd )
                {
                    p = sRecord.pulPosition = sRecord.pulBuffer;
                    *VIC1_SOFTINT           = INT1_UNUSED2;
                }    

				while ( dwFillCount -- )
				{
					*p++ = *SAI_RX0_LEFT;
					*p++ = *SAI_RX0_RIGHT;
				}

                sRecord.pulPosition= p;
            }
            else
            {
				while ( dwFillCount -- )
				{
					ulTemp = *SAI_RX0_LEFT;
					ulTemp = *SAI_RX0_RIGHT;
				}
			}
		}
    }
       
}

//****************************************************************************
// OEMInterruptHandler
//****************************************************************************
// This checks the timer first, then the other interrupts.  This could
// be rewritten using the priority registers in the ARM vectored interrupt
// controller, but I don't think that is currently necessary .
// 
//

int OEMInterruptHandler(unsigned int ra)
{
    register ULONG   ulVic1Irq, ulVic2Irq;
    DWORD retval;
    LARGE_INTEGER tmpCurTicks;

    //
    // Read the interrupt status registers.
    //
    ulVic1Irq   = *VIC1_IRQSTATUS;
    ulVic2Irq   = *VIC2_IRQSTATUS;

    //
    // Set the default value to nop
    //   
    retval      = SYSINTR_NOP;

    //       
    // Fake CPUEnterIdle needs to know about interrupt firing.
    //
    if(ulVic1Irq & INT1_TIMER1)
    {
        //
        // Temporary hack for the PS2 keyboard driver.
        /*
        if((gdwInterruptMask2 & INT2_SPI) && (*SPI_SR & SPISR_RNE) && !fPS2Int)
        {
            fPS2Int         = 1;
            *VIC2_INTCLEAR  = INT2_SPI;
            retval          = SYSINTR_SPI;   
        }
        else*/
        {
            retval = TimerInterrupt();
            CPUClearSysTimerIRQ();
        }
        
        //
        //  Check if RTC Alarm arrived when TimerInterrupt returns NOP.
        //
        if( (gfRTCAlarm) && (retval == SYSINTR_NOP) )
        {
            // Tell the world that we were here....
            #if (1 == DEBUG_ALARM)
                OEMWriteDebugByte('e');
            #endif  // ( DEBUG_ALARM )
            tmpCurTicks.QuadPart = CurTicks.QuadPart ;
            if (gliRTCAlarmTicks.QuadPart <= tmpCurTicks.QuadPart)
            {
                #if (1 == DEBUG_ALARM)
                    // Tell the world that the interrupt was hit...
                    OEMWriteDebugByte('t');
                    OEMWriteDebugByte('\r');
                    OEMWriteDebugByte('\n');
                #endif  // ( DEBUG_ALARM )
                gfRTCAlarm = FALSE;
                retval = SYSINTR_RTC_ALARM;
            }
        }
    }

    else
    {              
	
        //
        // If we're timing interrupts, keep track of when this one came in
        //
        if (fIntrTime) 
        {
            //
            // Subtract off dwReschedIncrment since interrupt hasn't been cleared
            //
            dwIsrTime1 = PerfCountSinceTick();
            wNumInterrupts++;
        }
        // 
        // 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.
        //
        //gfResumeFlag = TRUE;

        //
        // This was not a timer interrupt, must be a device interrupt.
        // Change the priority of the interrupt by changing the order that
        // the interrupt is processed.
        //
        //
        // Ethernet interrupt.
        //
        if(ulVic2Irq & INT2_ETHERNET)
        {
            *VIC2_INTCLEAR = INT2_ETHERNET;
            retval = SYSINTR_ETHER;   
        }
        //
        // USB interrupt
        //
        else if(ulVic2Irq & INT2_USB)
        {
            *VIC2_INTCLEAR = INT2_USB;
            retval = SYSINTR_USB;   
        }
        //
        // Check the serial port interrupts.
        //
        else if(ulVic2Irq & INT2_UART1)
        {
            *VIC2_INTCLEAR = INT2_UART1;
            retval = SYSINTR_UART1;   
        }
        else if(ulVic2Irq & INT2_UART2)
        {
            *VIC2_INTCLEAR = INT2_UART2;
            retval = SYSINTR_UART2;   
        }
        else if(ulVic2Irq & INT2_UART3)
        {
            *VIC2_INTCLEAR = INT2_UART3;
            retval = SYSINTR_UART3;   
        }

//#ifdef BSP_EXT_UART
		//
		// Check to see if it is the GPIO interrupt
		//
		else if(ulVic2Irq & INT2_GPIO)
		{
		UINT temp ;
		//*VIC2_INTCLEAR = INT2_GPIO;
		temp = *GPIO_INTSTATUSB ;
			//
			// Check to see if it is the GPIO interrupt from UART4
			//
			if( (temp & EGPIO_UART4_INT) == EGPIO_UART4_INT )
			{
				UINT value;
								
				value = *GPIO_BINTEN;
				value &= ~EGPIO_UART4_INT;
				*GPIO_BINTEN = value; // Disable all interrupt.

				*GPIO_BEOI = EGPIO_UART4_INT; // Clean all previous 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;

				//value = *GPIO_BINTEN;
				//value |= EGPIO_UART4_INT; // Enable interrupt
				//*GPIO_BINTEN = value;	

				//*VIC2_INTCLEAR = INT2_GPIO;
				//*VIC2_INTENABLE = INT2_GPIO;
				retval  = SYSINTR_UART4;
			}
			else if( (temp & EGPIO_UART5_INT) == EGPIO_UART5_INT )
			{
				UINT value;
				
				value = *GPIO_BINTEN;
				value &= ~EGPIO_UART5_INT;
				*GPIO_BINTEN = value; // Disable all interrupt.

				*GPIO_BEOI = EGPIO_UART5_INT; // Clean all previous interrupt

				//value = *GPIO_BINTTYPE1;
				////value &= ~EGPIO_UART5_INT; // level trigure.
				//value |= EGPIO_UART5_INT;
				//*GPIO_BINTTYPE1 = value;

				//value = *GPIO_BINTTYPE2;
				//value |= EGPIO_UART5_INT; // high level 
				//*GPIO_BINTTYPE2 = value;

				//value = *GPIO_BINTEN;
				//value |= EGPIO_UART5_INT; // Enable interrupt
				//*GPIO_BINTEN = value;	

				//*VIC2_INTCLEAR = INT2_GPIO;
				//*VIC2_INTENABLE = INT2_GPIO;
				retval  = SYSINTR_UART5;
			}
			else if( (temp & EGPIO_UART6_INT) == EGPIO_UART6_INT )
			{
				UINT value;
								
				value = *GPIO_BINTEN;
				value &= ~EGPIO_UART6_INT;
				*GPIO_BINTEN = value; // Disable all interrupt.

				*GPIO_BEOI = EGPIO_UART6_INT; // Clean all previous interrupt

				//value = *GPIO_BINTTYPE1;
				////value &= ~EGPIO_UART6_INT; // level trigure.
				//value |= EGPIO_UART6_INT;
				//*GPIO_BINTTYPE1 = value;

				//value = *GPIO_BINTTYPE2;
				//value |= EGPIO_UART6_INT; // high level 
				//*GPIO_BINTTYPE2 = value;

				//value = *GPIO_BINTEN;
				//value |= EGPIO_UART6_INT; // Enable interrupt
				//*GPIO_BINTEN = value;	

				//*VIC2_INTCLEAR = INT2_GPIO;
				//*VIC2_INTENABLE = INT2_GPIO;
				retval  = SYSINTR_UART6;
			}
			else if( (temp & EGPIO_UART7_INT) == EGPIO_UART7_INT )
			{
				UINT value;
								
				value = *GPIO_BINTEN;
				value &= ~EGPIO_UART7_INT;
				*GPIO_BINTEN = value; // Disable all interrupt.

				*GPIO_BEOI = EGPIO_UART7_INT; // Clean all previous interrupt

				//value = *GPIO_BINTTYPE1;
				////value &= ~EGPIO_UART7_INT; // level trigure.
				//value |= EGPIO_UART7_INT;
				//*GPIO_BINTTYPE1 = value;

⌨️ 快捷键说明

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