📄 bvdisrs.c
字号:
/*
** INTEL CONFIDENTIAL
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors. Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
*/
/*++
Module Name: $Workfile: bvdisrs.c $
Abstract:
Intel XScale Microarchitecture platform interrupt service routines for
the Bulverde processor.
Notes:
Created: May 8, 2002
--*/
#include <windows.h>
#include <bldver.h>
#include <nkintr.h>
#include <oalintr.h>
#include "drv_glob.h"
#include "bvd1.h"
#include "bvd1bd.h"
#include "timer.h"
#include "pmu.h"
#include "dmacbits.h"
#include "pcf.h"
#include "drvlib.h"
#include "Xllp_lcd.h"
#include "Ind.h"
#define CLEAR_INT(reg,mask) reg &= ~mask
extern DWORD CurMSec;
extern volatile ULARGE_INTEGER CurTicks;
#if (WINCEOSVER <= 300)
extern DWORD DiffMSec;
extern DWORD ticksleft, dwSleepMin, dwPreempt;
#else
extern DWORD dwReschedTime;
#endif
#if (WINCEOSVER > 400)
extern DWORD dwProfilerIncrement;
extern void ProfilerHit(DWORD);
//
// For Interrupt Latency Support
//
extern DWORD dwIsrTime1, dwIsrTime2;
extern BOOL fIntrTime;
extern WORD wNumInterrupts;
extern DWORD dwIntrTimeCountdown;
extern DWORD dwIntrTimeCountdownRef;
extern DWORD PerfCountSinceTick();
#else
extern int (*PProfileInterrupt)(void);
#endif
extern XSC1GetSPSR(void);
extern WarmStart(void);
extern void EthernetInterruptDisable();
unsigned int MyEPC;
int iProtectTimeFlag = 0;
//
// OSTM0TimerISR
//
// Timer M0 - Scheduler
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM0TimerISR(unsigned int ra)
{
unsigned long reschedIncrement = RESCHED_INCREMENT;
unsigned long reschedPeriod = RESCHED_PERIOD;
volatile XLLP_OST_T *v_pOSTReg = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
TIMER_M0_INT_DIS(v_pOSTReg->oier); // Disable the M0 interrupt
#if (WINCEOSVER <= 400)
if (PProfileInterrupt)
{
MyEPC=ra;
//
// The profiler rearms and enables the match timer
//
return PProfileInterrupt();
}
else
#endif
{
//
// Update match register for next timer firing
//
v_pOSTReg->osmr0 += reschedIncrement;
#if (WINCEOSVER > 400)
//
// For ILTiming, track when this one came in
//
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
}
#endif
//
// Increment the global variables
//
CurTicks.QuadPart += reschedIncrement;
#if (CE_MAJOR_VER <= 0x0003)
DiffMSec += reschedPeriod;
#endif
CurMSec += reschedPeriod;
//
// Adjust M0 if too close to oscr
// Delta value based on 2x worst case ISR latency
//
if ( ((long)(v_pOSTReg->osmr0 - v_pOSTReg->oscr0)) < 20 )
{
v_pOSTReg->osmr0 = v_pOSTReg->oscr0 + reschedIncrement;
#if (WINCEOSVER <= 300)
DiffMSec += reschedPeriod;
#endif
CurMSec += reschedPeriod;
}
//Clear and enable the interrupt
TIMER_M0_INT_CLR(v_pOSTReg->ossr);
TIMER_M0_INT_EN(v_pOSTReg->oier);
#if (WINCEOSVER > 400)
if (fIntrTime)
{
dwIntrTimeCountdown--;
if (dwIntrTimeCountdown == 0)
{
dwIntrTimeCountdown = dwIntrTimeCountdownRef;
wNumInterrupts = 0;
dwIsrTime2 = PerfCountSinceTick();
return SYSINTR_TIMING;
}
}
#endif
//
// Reschedule for threads on sleep queue (ticksleft);
// Sleep timer expiring and we need to check the sleep queue (dwSleepMin);
// Thread is close to being preempted (dwPreempt).
//
#if (WINCEOSVER <= 300)
if (ticksleft || (dwSleepMin && (DiffMSec >= dwSleepMin))
|| (dwPreempt && (DiffMSec >= dwPreempt)))
#else
if ((int) (CurMSec - dwReschedTime) >= 0)
#endif
{
return SYSINTR_RESCHED;
}
}
return SYSINTR_NOP;
}
//
// OSTM1TimerISR
//
// Timer M1 - Touch
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM1TimerISR(unsigned int ra)
{
volatile XLLP_OST_T *v_pOSTReg;
volatile XLLP_INTC_T *v_pICReg;
PDRIVER_GLOBALS v_pDrvGlob;
v_pOSTReg = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
v_pICReg = (volatile XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
v_pDrvGlob = (PDRIVER_GLOBALS)DRIVER_GLOBALS_U_VIRTUAL;
INTC_M1_INT_DIS(v_pICReg->icmr);
TIMER_M1_INT_CLR(v_pOSTReg->ossr);
#if (WINCEOSVER > 400)
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
}
#endif
return SYSINTR_TOUCH_CHANGED;
}
//
// OSTM2TimerISR
//
// Timer M2 - Profiler - only for WINCEOSVER > 400
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM2TimerISR(unsigned int ra)
{
volatile XLLP_OST_T *v_pOSTReg;
v_pOSTReg = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
#if (WINCEOSVER > 400)
//
// Service the profiler interrupt.
//
TIMER_M2_INT_DIS(v_pOSTReg->oier); // Disable the M0 interrupt
v_pOSTReg->osmr2 = v_pOSTReg->oscr0 + dwProfilerIncrement;
//Clear and enable the interrupt
TIMER_M2_INT_CLR(v_pOSTReg->ossr);
TIMER_M2_INT_EN(v_pOSTReg->oier);
ProfilerHit(ra);
#endif
return SYSINTR_NOP;
}
//
// OSTM3TimerISR
//
// Timer M3 - DVM/DFM
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM3TimerISR(unsigned int ra)
{
volatile XLLP_OST_T *v_pOSTReg;
volatile XLLP_INTC_T *v_pICReg;
PDRIVER_GLOBALS v_pDrvGlob;
v_pOSTReg = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
v_pICReg = (volatile XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
v_pDrvGlob = (PDRIVER_GLOBALS)DRIVER_GLOBALS_U_VIRTUAL;
TIMER_M3_INT_DIS(v_pOSTReg->oier);
INTC_M3_INT_DIS(v_pICReg->icmr);
TIMER_M3_INT_CLR(v_pOSTReg->ossr);
#if (WINCEOSVER > 400)
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
}
#endif
return SYSINTR_DVM;
}
WORD DispCurPos = 0;
//
// OSTM4_11TimerISR
//
// Timer Match Registers M4-M11
//
// Inputs:
// ra - return address of the interrupted routine
//
int OSTM4_11TimerISR(unsigned int ra)
{
volatile XLLP_INTC_T *v_pICReg = (volatile XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
volatile XLLP_OST_T *v_pOSTRegs = (volatile XLLP_OST_T *)OST_BASE_U_VIRTUAL;
volatile XLLP_GPIO_T *v_pGPIOReg = (volatile XLLP_GPIO_T *)GPIO_BASE_U_VIRTUAL;
volatile XLLP_RTC_T *v_pRTCReg = (volatile XLLP_RTC_T *)RTC_BASE_U_VIRTUAL;
PDRIVER_GLOBALS v_pDrvGlob = (PDRIVER_GLOBALS)DRIVER_GLOBALS_U_VIRTUAL;
volatile WORD *pPixel;
WORD row, col;
unsigned int iRtcAlarmTicks;
static unsigned short usTimerTicks = 0 ;
static BYTE bGpio0LowLevel = 0;
int percentCo;
int iIntRet = SYSINTR_NOP;
percentCo = GetPercentCo();
INTC_M4XX_INT_DIS(v_pICReg->icmr);
if(v_pOSTRegs->ossr & XLLP_OSSR_M4)
{
TIMER_M4_INT_DIS(v_pOSTRegs->oier);
TIMER_M4_INT_CLR(v_pOSTRegs->ossr);
pPixel = (volatile WORD *)FRAME_BUFFER_0_BASE_VIRTUAL;
if (LCD_FLAG != *(volatile DWORD *)pPixel)
goto ostm4_11TimerIsr_exit;
for(row = GUAGE_Y1 + 3; row < GUAGE_Y2 - 3; row ++)
for(col = percentCo*DispCurPos; col < percentCo*(DispCurPos + 1); col++)
*(pPixel + row * SCREENWIDTH + col + GUAGE_X1 + 3) = GUAGE_COLOR;
if ( ++DispCurPos >= 99 )
memset((void*)pPixel, 0xFF, SCREENWIDTH * SCREENHEIGHT * 2);
TIMER_M4_INT_EN(v_pOSTRegs->oier);
}
else if(v_pOSTRegs->ossr & XLLP_OSSR_M5)
{
TIMER_M5_INT_DIS(v_pOSTRegs->oier);
TIMER_M5_INT_CLR(v_pOSTRegs->ossr);
if(!(v_pGPIOReg->GPLR0 & XLLP_BIT_0))
{
if( (bGpio0LowLevel == 0) )
{
bGpio0LowLevel = 1;
usTimerTicks = 0;
}
else
{
usTimerTicks++ ;
if(usTimerTicks >= 36)
{
//
// Power OFF interrupt
bGpio0LowLevel = 0 ;
if(!iProtectTimeFlag)
{
RETAILMSG(1,(TEXT("Press pwrButton long than a times,to enter sleep.\r\n"))) ;
iProtectTimeFlag = 1;
iIntRet = SYSINTR_POWER;
}
else
{
RETAILMSG(1,(TEXT("Press pwrButton long than a times,But...\r\n"))) ;
/*
* Here , to assure rtc-alarm intr will being triggered we detect all rtc-alarm trigger
* conditions: INTC_MASK , RTC_ALARM ENABLE, and MATCH_COUNT.
*/
if(!(v_pICReg->icmr & XLLP_INTC_RTCALARM))
{
RETAILMSG(1,(TEXT("RTC intr are mask ! \r\n"))) ;
INTC_RTC_TIC_INT_EN(v_pICReg->icmr);
}
if(!(v_pRTCReg->rtsr & XLLP_RTSR_ALE))
{
RETAILMSG(1,(TEXT("RTC alarm intr are disalbed ! \r\n"))) ;
RT_ALARM_INT_EN(v_pRTCReg->rtsr);
}
if((iRtcAlarmTicks = v_pRTCReg->rtar) < v_pRTCReg->rcnr)
{
RETAILMSG(1,(TEXT("RTC alarm match tick < current tick ! \r\n"))) ;
iRtcAlarmTicks = v_pRTCReg->rcnr;
v_pRTCReg->rtar = iRtcAlarmTicks + 5;
}
else if((iRtcAlarmTicks = v_pRTCReg->rtar) - v_pRTCReg->rcnr > 5)
{
RETAILMSG(1,(TEXT("RTC alarm match tick > current tick too much! \r\n"))) ;
iRtcAlarmTicks = v_pRTCReg->rcnr;
v_pRTCReg->rtar = iRtcAlarmTicks + 5;
}
}
}
}
}
else
{
if( (bGpio0LowLevel == 1) ) ///--- backlight intr.
{
if(usTimerTicks<36)
{
iIntRet = SYSINTR_SCREEN ;
}
}
bGpio0LowLevel = 0;
usTimerTicks = 0;
}
TIMER_M5_INT_EN(v_pOSTRegs->oier);
}
ostm4_11TimerIsr_exit:
INTC_M4XX_INT_EN(v_pICReg->icmr);
return iIntRet;
}
//
// RTCAlarmISR
//
// Inputs:
// ra - return address of the interrupted routine
//
int RTCAlarmISR(unsigned int ra)
{
volatile XLLP_RTC_T *v_pRTCReg;
v_pRTCReg = (volatile XLLP_RTC_T *)RTC_BASE_U_VIRTUAL;
RT_ALARM_INT_DIS(v_pRTCReg->rtsr); // mask interrupt
RT_ALARM_INT_CLR(v_pRTCReg->rtsr); // clear the interrupt
///--- this intr are trigged when wake up from sleep.
iProtectTimeFlag = 0; ///--- here reset the flag .
#if (WINCEOSVER > 400)
if (fIntrTime)
{
dwIsrTime1 = PerfCountSinceTick();
wNumInterrupts++;
}
#endif
RETAILMSG(1,(TEXT("RTC Alarm Intr Ented.\r\n")));
///--- do not reenable intr .
return SYSINTR_RTC_ALARM;
}
//
// GPIO0ISR - Power OFF ISR
//
// Inputs:
// ra - return address of the interrupted routine
//
int GPIO0ISR(unsigned int ra)
{
volatile XLLP_INTC_T *v_pICReg;
volatile XLLP_GPIO_T *v_pGPIOReg;
int iIntrRet = SYSINTR_NOP;
v_pICReg = (volatile XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
v_pGPIOReg = (volatile XLLP_GPIO_T *)GPIO_BASE_U_VIRTUAL;
// mask interrupt & clear the edge detection
//
INTC_GPIO0_INT_DIS (v_pICReg->icmr);
GEDR_GPIO0_EDGE_CLR (v_pGPIOReg->GEDR0);
INTC_GPIO0_INT_EN (v_pICReg->icmr);
return iIntrRet;
}
//
// GPIO1ISR - Power Manage ISR,from PCF50606
//
// Inputs:
// ra - return address of the interrupted routine
//
int GPIO1ISR(unsigned int ra)
{
volatile XLLP_INTC_T *v_pICReg;
volatile XLLP_GPIO_T *v_pGPIOReg;
/*
PDRIVER_GLOBALS v_pDrvGlob;
XLLP_OST_T* v_pOstReg;
PMRC_REGS *pwrRegs;
MEMC_STRUCT *pmemRegs;
int interruptType = SYSINTR_NOP;
static int number1 = 0;
static int number2 = 0;
v_pDrvGlob = (PDRIVER_GLOBALS)DRIVER_GLOBALS_U_VIRTUAL;
v_pOstReg = (XLLP_OST_T*)OST_BASE_U_VIRTUAL;
pwrRegs = (PMRC_REGS *)PWR_BASE_U_VIRTUAL;
pmemRegs = (MEMC_STRUCT*)MEMC_BASE_U_VIRTUAL;
*/
v_pICReg = (volatile XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
v_pGPIOReg = (volatile XLLP_GPIO_T *)GPIO_BASE_U_VIRTUAL;
INTC_GPIO1_INT_DIS (v_pICReg->icmr);
GEDR_GPIO1_EDGE_CLR (v_pGPIOReg->GEDR0);
INTC_GPIO1_INT_EN (v_pICReg->icmr);
return SYSINTR_NOP;
}
//
// GPIOxISR -
//
// Inputs:
// ra - return address of the interrupted routine
//
int GPIOxISR(unsigned int ra)
{
volatile XLLP_INTC_T *v_pICReg;
volatile XLLP_GPIO_T *v_pGPIOReg;
PDRIVER_GLOBALS v_pDrvGlob;
int interruptType;
volatile IND_CTRL *v_PCMCIA;
v_pICReg = (volatile XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
v_pGPIOReg = (volatile XLLP_GPIO_T *)GPIO_BASE_U_VIRTUAL;
v_pDrvGlob = (PDRIVER_GLOBALS)DRIVER_GLOBALS_U_VIRTUAL;
//Enable logic PCMCIA
v_PCMCIA = (volatile IND_CTRL *)INDICATOR_LIGHT_BASE_U_VIRTUAL;
INTC_GPIOXX_2_INT_DIS (v_pICReg->icmr);
if( v_pGPIOReg->GEDR1 & (0x1<<20) )
{
v_pGPIOReg->GFER1 &= ~(0x1u<<20) ;
//clear interrupt bit
GEDR3_GPIO52_EDGE_CLR(v_pGPIOReg->GEDR1) ;
interruptType=SYSINTR_TOUCH ;
//RETAILMSG(1,(TEXT("---------------Touch Interrupt----------\r\n")));
}
else if(v_pGPIOReg->GEDR0 & 0x200)
{
GEDR_GPIO9_EDGE_CLR(v_pGPIOReg->GEDR0);
interruptType = SYSINTR_ETHERNET;
}
/*else if(v_pGPIOReg->GEDR0 & 0x2000)
{
GEDR_GPIO13_EDGE_CLR(v_pGPIOReg->GEDR0);
interruptType = SYSINTR_MARATHON;
}*/
else if(v_pGPIOReg->GEDR0 & 0x4000)
{
if(v_PCMCIA->intr & PCMCIA0_INT_ENABLE)
{
while(!(v_PCMCIA->status & PCMCIA_CONTROL_IDLE));
v_PCMCIA->intrmask &= PCMCIA0_MASK;
GPIO14_FALLING_EDGE_OFF(v_pGPIOReg->GEDR0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -