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

📄 int920.c

📁 三星2410的BSP开发包
💻 C
字号:
/*++
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.
Copyright (c) 2001. Samsung Electronics, co. ltd  All rights reserved.

Module Name:  

Abstract:

	ARM920(S3C2410) interrupt service routine

rev:
	2002.4.3	: first S3C2410 version (SOC)	

	2002.2.5	: system tick modification (kwangyoon LEE, kwangyoon@samsung.com)	
					- one shot timer
	2002.1.29	: bug fixups (kwangyoon LEE, kwangyoon@samsung.com)	
					- system tick interrupt
	2002.1.28	: CE.NET port (kwangyoon LEE, kwangyoon@samsung.com)
	2002.1.22	: Add USBD interrupt (kwangyoon LEE, kwangyoon@samsung.com)

Notes: 
--*/

#include <windows.h>
#include <nkintr.h>
#include <oalintr.h>
#include "p2.h"
#include "p2debug.h"
#include "odoregs.h"
#include "drv_glob.h"

#include <S2410.h>

extern DWORD CurMSec;
extern DWORD DiffMSec;

#if (CE_MAJOR_VER == 0x0003)
	extern DWORD ticksleft, dwSleepMin, dwPreempt;
	extern DWORD DiffMSec;
#else
	extern DWORD dwReschedTime;
#endif

extern DWORD AlarmTime;
extern volatile LARGE_INTEGER CurTicks;
extern DWORD dwReschedIncrement;
extern int (*PProfileInterrupt)(void);

extern DWORD dwIsrTime1, dwIsrTime2;
extern BOOL fIntrTime, fIntrTimeToggle;
extern WORD wNumInterrupts;    // Reset by a read of the ISR times from the IST
extern DWORD dwIntrTimeCountdown;
extern DWORD dwIntrTimeCountdownRef;
extern DWORD dwSPC;
extern DWORD PerfCountSinceTick();
extern BOOL fInterruptFlag;

DWORD OEMTranslateIrq(DWORD dwIrq)
{
    return dwIrq;
}
DWORD OEMTranslateSysIntr(DWORD SysIntr)
{
    return (SysIntr<SYSINTR_FIRMWARE?(DWORD)-1:SysIntr);
}

void OEMInterruptHandlerFIQ() 
{
}


int flag = 1;
unsigned int tCnt = 0;
unsigned int ttt = 0;



int OEMInterruptHandler(unsigned int ra) 
{
	volatile INTreg *s2410INT; 
	volatile IOPreg *s2410IOP;
    volatile PWMreg *s2410PWM;

	unsigned int IntPendVal;
	unsigned int SubIntPendVal;	// for serial

    
	s2410INT = (INTreg *)INT_BASE;
	s2410IOP = (IOPreg *)IOP_BASE;
    s2410PWM = (PWMreg *)PWM_BASE;

	IntPendVal = s2410INT->rINTOFFSET;
    
	// Fake CPUEnterIdle needs to know about interrupt firing.
	fInterruptFlag = TRUE;

    if (fIntrTime) {
        //
        // We're doing interrupt timing. Get Time to ISR. We subtract TIMER_COUNTDOWN
        // here because the compare register has not been updated.
        //
        dwIsrTime1 = PerfCountSinceTick() - dwReschedIncrement;
        dwSPC = ra;
        wNumInterrupts++;
    }

	//
	// Check the timer interrupt.
	//
	if (IntPendVal == INTSRC_TIMER4) 
	{
                             		DWORD ttmp;
                             
                             		RETAILMSG(0, (TEXT("T")));
                                     
                             	    s2410PWM->rTCNTB4 = dwReschedIncrement;
                             
                             		ttmp = s2410PWM->rTCON & (~(0xf << 20));
                             
                             		s2410PWM->rTCON = ttmp | (2 << 20);		/* update TCVNTB4, stop					*/
                             		s2410PWM->rTCON = ttmp | (1 << 20);		/* one-shot mode,  start				*/
                             
                                            //
                                            // Update the global variables.
                                            //
                                            #if (CE_MAJOR_VER == 0x0003)
                                            		DiffMSec += RESCHED_PERIOD;
                                            #endif
                                            		CurMSec  += RESCHED_PERIOD;
                             
                                                          
                             		CurTicks.QuadPart += dwReschedIncrement;
                                     
                             		//
                             		// Clear the interrupt
                             		//
                             		s2410INT->rSRCPND = BIT_TIMER4;        
                             		s2410INT->rINTPND = BIT_TIMER4;
                             		
                             		if (fIntrTime) 
                             		{
                                                          			//
                                                          			// We're doing interrupt timing. Every other tick is a RESCHED.
                                                          			//
                                                          			dwIntrTimeCountdown--;
                                                                          
                                                          			if (dwIntrTimeCountdown == 0) {
                                                          				dwIntrTimeCountdown = dwIntrTimeCountdownRef;
                                                          				wNumInterrupts = 0;
                                                                              
                                                          				dwIsrTime2 = PerfCountSinceTick();
                                                          				return (SYSINTR_TIMING);
                                                          			} else {
                                                                           		#if (CE_MAJOR_VER == 0x0003)
                                                                           				if (ticksleft || (dwSleepMin && (dwSleepMin <= DiffMSec)) || (dwPreempt && (dwPreempt <= DiffMSec)))
                                                                           		#else
                                                                           				if ((int) (CurMSec - dwReschedTime) >= 0)
                                                                           		#endif
                                                          						return SYSINTR_RESCHED;
                                                          			}    
                             		} else {
                                                               #if (CE_MAJOR_VER == 0x0003)
                                                               			if (ticksleft || (dwSleepMin && (DiffMSec >= dwSleepMin)) || (dwPreempt && (DiffMSec >= dwPreempt)))
                                                               #else
                                                               			if ((int) (CurMSec - dwReschedTime) >= 0)
                                                               #endif
                             
                                                   		{
                                                   				RETAILMSG(0, (TEXT("CurMSec=%x, dwReschedTime=%x\r\n"), CurMSec, dwReschedTime));
                                                   				return SYSINTR_RESCHED;
                                                   		}
                             					return SYSINTR_NOP;
                             		}

		
	} else if (IntPendVal == INTSRC_EINT1) { // Keyboard interrupt is connected to EINT1.
                    RETAILMSG(0, (TEXT("INT:Keyboard Interrupt \r\n")));
                    s2410INT->rINTMSK |= BIT_EINT1;
                    s2410INT->rSRCPND = BIT_EINT1;        
                    s2410INT->rINTPND = BIT_EINT1;
                    return SYSINTR_KEYBOARD;
	}
	else if (IntPendVal == INTSRC_EINT3) { // PCMCIA interrupt is connected to EINT3. (nINT_P_DEV)
       		DEBUGMSG(1, (TEXT("INT:SYSINTR_PCMCIA_STATE INT\r\n")));
       		s2410INT->rINTMSK |= BIT_EINT3;
       		s2410INT->rSRCPND = BIT_EINT3;        
       		s2410INT->rINTPND = BIT_EINT3;
                               
       		return SYSINTR_PCMCIA_STATE;
	}  
	else if (IntPendVal == INTSRC_EINT8_23) { // EINT8 ~ 23
				DEBUGMSG(1, (TEXT("INT:EINT8_23 : %x\r\n"), s2410IOP->rEINTPEND));
				DEBUGMSG(1, (TEXT("rEINTMASK %x\r\n"), s2410IOP->rEINTMASK));
				//		s2410INT->rINTMSK |= BIT_EINT8_23;

				if (s2410IOP->rEINTPEND & 0x100)	// EINT8 : PCMCIA_LEVEL
				{
					DEBUGMSG(1, (TEXT("INT:SYSINTR_PCMCIA_LEVEL INT\r\n")));
					s2410IOP->rEINTMASK |= 0x100;
					s2410IOP->rEINTPEND = 0x100;

					s2410INT->rSRCPND = BIT_EINT8_23;        
					s2410INT->rINTPND = BIT_EINT8_23;

					return SYSINTR_PCMCIA_LEVEL;
				}
				else if (s2410IOP->rEINTPEND & 0x200)	// EINT9 : CS8900
				{
					DEBUGMSG(1, (TEXT("INT:SYSINTR_ETHER INT\r\n")));
					s2410IOP->rEINTMASK |= 0x200;
					s2410IOP->rEINTPEND = 0x200;

					s2410INT->rSRCPND = BIT_EINT8_23;        
					s2410INT->rINTPND = BIT_EINT8_23;

					return SYSINTR_ETHER;
				}
				else
				{
					RETAILMSG(0, (TEXT("INT:???\r\n")));
					s2410INT->rSRCPND = BIT_EINT8_23;        
					s2410INT->rINTPND = BIT_EINT8_23;

					return SYSINTR_NOP;
				}					
	}
	else if (IntPendVal == INTSRC_ADC) { 	// INTSRC_ADC
		s2410INT->rINTSUBMSK |= BIT_SUB_TC;
		s2410INT->rSRCPND     = BIT_ADC;	/* Interrupt Clear			*/
		s2410INT->rINTPND     = BIT_ADC;
		s2410INT->rINTMSK    |= BIT_ADC;

					RETAILMSG(0, (TEXT("SYSINTR_TOUCH \r\n")));

			
		return SYSINTR_TOUCH;
	}
	else if (IntPendVal == INTSRC_TIMER3) { // INTSRC_TIMER3
		s2410INT->rSRCPND  = BIT_TIMER3;	/* Interrupt Clear			*/
		s2410INT->rINTPND  = BIT_TIMER3;
		s2410INT->rINTMSK |= BIT_TIMER3;

					RETAILMSG(0, (TEXT("SYSINTR_TOUCH_CHANGED \r\n")));


		return SYSINTR_TOUCH_CHANGED;
	}	     
	else if (IntPendVal == INTSRC_EINT0)  { // POWER BUTTON
		s2410INT->rSRCPND  = BIT_EINT0;	/* Interrupt Clear				*/
		s2410INT->rINTPND  = BIT_EINT0;
		s2410INT->rINTMSK |= BIT_EINT0;

		return SYSINTR_POWER;	
	}

	else if(IntPendVal == INTSRC_DMA2) {  // AUDIO DMA
            s2410INT->rINTMSK |= BIT_DMA2;
            s2410INT->rSRCPND = BIT_DMA2;
            s2410INT->rINTPND = BIT_DMA2;

            return SYSINTR_AUDIO;
	}

	// For USB.. 
/*lse if(IntPendVal == INTSRC_USBH) {
			        DEBUGMSG(1,(TEXT("INT:USB Interrupt \r\n")));
		       
		            s2410INT->rINTMSK |= BIT_USBH;
		            s2410INT->rSRCPND = BIT_USBH;        
		            s2410INT->rINTPND = BIT_USBH;
		            return SYSINTR_USB;     
        } */
        else if(IntPendVal == INTSRC_USBD) {
		            s2410INT->rINTMSK |= BIT_USBD;
		            s2410INT->rSRCPND = BIT_USBD;
		            s2410INT->rINTPND = BIT_USBD;
		            DEBUGMSG(1,(TEXT("USB DEVICE Intr Occured\r\n")));
		            RETAILMSG(1,(TEXT("USB DEVICE Intr Occured\r\n")));
		            return SYSINTR_USBD;
        }

	// For Serial & IRDA
		else if(IntPendVal == INTSRC_UART0) {  // SERIAL
			//
			// In this ISR, I clear the interrupt pending register only.
			// The source pending register has to be cleared at IST.
			// UART0 (serial port) Interrupt
			RETAILMSG(0, (TEXT("INT:SYSINTR_SERIAL INT\r\n")));
			SubIntPendVal = s2410INT->rSUBSRCPND;

			if(SubIntPendVal & INTSUB_ERR0) {
				s2410INT->rINTSUBMSK |= INTSUB_ERR0;
			}
			else if(SubIntPendVal & INTSUB_RXD0) {
				s2410INT->rINTSUBMSK |= INTSUB_RXD0;
			}
			else if(SubIntPendVal & INTSUB_TXD0) {
				s2410INT->rINTSUBMSK |= INTSUB_TXD0;
			}
			else
				return SYSINTR_NOP;


			SubIntPendVal = s2410INT->rSUBSRCPND;


			s2410INT->rINTMSK |= BIT_UART0;
			s2410INT->rINTPND  = BIT_UART0;
			return SYSINTR_SERIAL;
	}
	else if(IntPendVal == INTSRC_UART2) {  // IRDA
			// UART2 (IrDA port) Interrupt
			SubIntPendVal = s2410INT->rSUBSRCPND;

			if(SubIntPendVal & INTSUB_ERR2) {
				s2410INT->rINTSUBMSK |= INTSUB_ERR2;
			}       
			else if(SubIntPendVal & INTSUB_RXD2) {
				s2410INT->rINTSUBMSK |= INTSUB_RXD2;
			}       
			else if(SubIntPendVal & INTSUB_TXD2) {
				s2410INT->rINTSUBMSK |= INTSUB_TXD2;
			}       
			else
				return SYSINTR_NOP;

			s2410INT->rINTMSK |= BIT_UART2;
			s2410INT->rINTPND  = BIT_UART2;
			return SYSINTR_IR;
	}
	
    return SYSINTR_NOP;
}

⌨️ 快捷键说明

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