📄 armint.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 "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;
extern VOID CPUPowerReset();
extern VOID OEMEmergencyPowerOff();
static USBD_GLOBALS *usbdShMem=&((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->usbd; //:-)
void UsbdClearEir(void); //:-)
DWORD OEMTranslateIrq(DWORD dwIrq)
{
return dwIrq;
}
DWORD OEMTranslateSysIntr(DWORD SysIntr)
{
return (SysIntr<SYSINTR_FIRMWARE?(DWORD)-1:SysIntr);
}
void OEMInterruptHandlerFIQ()
{
// This FIQ interrupt is from BAT_FLT.
volatile IOPreg *s2410IOP = (IOPreg *)IOP_BASE;
volatile INTreg *s2410INT = (INTreg *)INT_BASE;
s2410IOP->rGPFDAT = ~(0xa << 4); /* LED Off */
OEMEmergencyPowerOff();
while(1);
// RETAILMSG(1, (TEXT(">>> OEMInterruptHandlerFIQ \r\n")));
}
int flag = 1;
unsigned int tCnt = 0;
unsigned int ttt = 0;
int OEMInterruptHandler(unsigned int ra)
{
static BYTE nLED = 0x1;
volatile INTreg *s2410INT = (INTreg *)INT_BASE;
volatile IOPreg *s2410IOP = (IOPreg *)IOP_BASE;
volatile PWMreg *s2410PWM = (PWMreg *)PWM_BASE;
volatile MMCreg *s2410SDIO = (MMCreg *)MMC_BACE;
unsigned int IntPendVal;
unsigned int SubIntPendVal; // for serial
DWORD submask;
// jylee
volatile ADCreg *s2410ADC = (ADCreg *)ADC_BASE;
static DWORD HeartBeatCnt, HeartBeatStat;
static volatile struct udcreg *s2410USBD = (volatile struct udcreg *)(0xB1200140); // 0xB1200140
volatile BYTE usbd_eir = 0, usbd_uir = 0;
TOUCH_GLOBALS *odo_tsb; //Sample buffer stuff
// for this, You MUST modify bsp/inc/drv_glob.h.. check drv_glob.h_jylee
odo_tsb = &((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->tch;
// Update LEDs.
//
// if (nLED++ > 0xf) nLED = 0;
// OEMWriteDebugLED(0, ~nLED);
IntPendVal = s2410INT->rINTOFFSET; // Get pending IRQ mode interrupt in INTPND.
//if(!(IntPendVal==0xe))RETAILMSG(1,(TEXT("interrupt: %x\r\n"), IntPendVal));
// 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;
if (++HeartBeatCnt > 10)
{
HeartBeatCnt = 0;
HeartBeatStat ^= 1;
if (HeartBeatStat)
s2410IOP->rGPFDAT &= ~(1 << 4); /* LED 0 On */
else
s2410IOP->rGPFDAT |= (1 << 4); /* LED 0 Off */
}
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 tick counter.
//
CurTicks.QuadPart += dwReschedIncrement;
// Call the profile ISR if it's enabled.
//
if (PProfileInterrupt)
{
DWORD dwRetVal = SYSINTR_NOP;
dwRetVal = PProfileInterrupt();
if (dwRetVal == SYSINTR_RESCHED)
{
// Update the millisecond counter.
//
CurMSec += RESCHED_PERIOD;
#if (CE_MAJOR_VER == 0x0003)
DiffMSec += RESCHED_PERIOD;
#endif
}
// Clear the interrupt
//
s2410INT->rSRCPND = BIT_TIMER4;
if (s2410INT->rINTPND & BIT_TIMER4) s2410INT->rINTPND = BIT_TIMER4;
// Return whatever we got back from the profiling ISR.
//
return(dwRetVal);
}
// Update the millisecond counter.
//
#if (CE_MAJOR_VER == 0x0003)
DiffMSec += RESCHED_PERIOD;
#endif
CurMSec += RESCHED_PERIOD;
//
// Clear the interrupt
//
s2410INT->rSRCPND = BIT_TIMER4;
if (s2410INT->rINTPND & 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
{
return(SYSINTR_RESCHED);
}
return(SYSINTR_NOP);
}
}
else if(IntPendVal == INTSRC_MMC) // SD, MMC
{
s2410INT->rINTMSK |= BIT_MMC;
s2410INT->rSRCPND = BIT_MMC;
if (s2410INT->rINTPND & BIT_MMC) s2410INT->rINTPND = BIT_MMC;
//RETAILMSG(1, (TEXT("ARMINT.C-INT:INTSRC_MMC INT\r\n")));
if( s2410SDIO->rSDIDATSTA & (0x1<<9) ){
//RETAILMSG(1, (TEXT("INT:SYSINTR_SDMMC_SDIO_INTERRUPT INT\r\n")));
return SYSINTR_SDMMC_SDIO_INTERRUPT;
}
else {
//RETAILMSG(1, (TEXT("INT:SYSINTR_SDMMC INT\r\n")));
return SYSINTR_SDMMC;
}
}
else if(IntPendVal == INTSRC_DMA0) // SD DMA interrupt
{
s2410INT->rINTMSK |= BIT_DMA0;
s2410INT->rSRCPND = BIT_DMA0;
if (s2410INT->rINTPND & BIT_DMA0) s2410INT->rINTPND = BIT_DMA0;
return SYSINTR_DMA0;
}
else if (IntPendVal == INTSRC_EINT1) // Keyboard interrupt is connected to EINT1.
{
s2410INT->rINTMSK |= BIT_EINT1;
s2410INT->rSRCPND = BIT_EINT1;
if (s2410INT->rINTPND & BIT_EINT1) s2410INT->rINTPND = BIT_EINT1;
return(SYSINTR_KEYBOARD);
}
else if (IntPendVal == INTSRC_EINT2) // EINT2
{
s2410INT->rINTMSK |= BIT_EINT2;
s2410INT->rSRCPND = BIT_EINT2; /* Interrupt Clear */
if (s2410INT->rINTPND & BIT_EINT2) s2410INT->rINTPND = BIT_EINT2;
// RETAILMSG(1, (TEXT(">>> CPUPowerReset \r\n")));
RETAILMSG(1,(TEXT(">>> >>> Reset Button Pressed <<< <<< \r\n")));
CPUPowerReset();
return(SYSINTR_POWER);
}
else if (IntPendVal == INTSRC_EINT3) // PCMCIA interrupt is connected to EINT3. (nINT_P_DEV)
{
s2410INT->rINTMSK |= BIT_EINT3;
s2410INT->rSRCPND = BIT_EINT3;
if (s2410INT->rINTPND & BIT_EINT3) s2410INT->rINTPND = BIT_EINT3;
//RETAILMSG(1, (TEXT("ARMINT.C - SYSINTR_PCMCIA_STATE\r\n")));
return(SYSINTR_PCMCIA_STATE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -