📄 int920.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 + -