📄 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) 1995-1998 Microsoft Corporation
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <bldver.h>
#include <nkintr.h>
#include <oalintr.h>
#include "p2.h"
#include "p2debug.h"
#include "odoregs.h"
#include "drv_glob.h"
extern DWORD CurMSec;
#if (CE_MAJOR_VER == 0x0003)
extern DWORD DiffMSec;
#endif
int ArmInterruptHandler();
#ifdef SA1100
#include "int1100.c"
#endif
#ifdef ARM720
#include "int720.c"
#endif
#ifdef ARM920
#include "int920.c"
#endif
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
int
ArmInterruptHandler()
{
int iRet = SYSINTR_NOP;
#define GOTO_EXIT(x) {iRet = x; goto EXIT;}
UINT16 wPcmIntPending;
UINT16 wMrTemp;
UINT16 my_odo_mask_reg;
UINT16 my_odo_isr_reg;
UINT16 my_odo_csr_reg;
UINT16 my_odo_pci_reg0;
UINT16 my_odo_pci_reg1;
UINT16 my_odo_pci_int_reg0;
UINT16 my_odo_pci_int_reg1;
UINT16 my_coordinate;
UINT16 my_odo_intrMask;
UINT my_halptr;
volatile struct cpureg *odo_cpu;
volatile struct statreg *odo_sta;
volatile struct tsr *odo_tsr;
volatile struct pcireg *odo_pci;
TOUCH_GLOBALS *odo_tsb; //Sample buffer stuff
odo_cpu = (volatile struct cpureg *)CPU_BASE;
odo_sta = (volatile struct statreg *)CPU_STATUS_BASE;
odo_tsr = (volatile struct tsr *)TOUCH_SOUND_BASE;
odo_pci = (volatile struct pcireg *) (PCMCIA_BASE + 0x10);
odo_tsb = &((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->tch;
my_odo_mask_reg = odo_cpu->odo_cpuMr;
my_odo_isr_reg = odo_cpu->odo_cpuIsr;
my_odo_csr_reg = odo_sta->odo_cpuCsr;
my_odo_pci_reg0 = odo_pci->odo_pcmciaReg0;
my_odo_pci_reg1 = odo_pci->odo_pcmciaReg1;
my_odo_pci_int_reg0 = odo_pci->odo_pcmciaIntrReg0;
my_odo_pci_int_reg1 = odo_pci->odo_pcmciaIntrReg1;
my_odo_isr_reg &= my_odo_mask_reg;
if ( (my_odo_isr_reg & odo_touchAudioAdcIntr) != 0 )
{
// check for pen interrupt
if ( (odo_tsr->odo_ioAdcStr & odo_penIntr) && (odo_tsr->odo_intrMask & odo_penIntrMask) )
{
// clear the interrupt
odo_tsr->odo_ioAdcStr = odo_penIntr;
// copy coordinate to buffer
my_coordinate = odo_tsr->odo_ioAdcCntr & TOUCH_SAMPLE_VALID;
*(UINT16 *)(odo_tsb->halPointer+odo_tsb->coordCount) = my_coordinate;
odo_tsb->coordCount += 2;
if ( (odo_tsb->coordCount & 0x02) == 0 )
{
if ( odo_tsb->coordCount < TOUCH_MAX_COORD )
{
odo_tsr->odo_ioAdcCntr = TOUCH_X_REQ;
GOTO_EXIT(SYSINTR_NOP);
}
else
{
my_odo_intrMask = odo_tsr->odo_intrMask;
// unmask timer int
my_odo_intrMask |= odo_penTimingIntrMask;
// mask pen data interrupt
my_odo_intrMask &= ~odo_penIntrMask;
odo_tsr->odo_intrMask = my_odo_intrMask;
odo_tsb->semaphore = 0;
my_halptr = odo_tsb->halPointer;
my_halptr ^= TOUCH_CHG_BUF_MASK;
if ( my_halptr != odo_tsb->devDrvPointer )
{
odo_tsb->halPointer = my_halptr;
odo_tsb->status = TOUCH_PEN_SAMPLE;
GOTO_EXIT(SYSINTR_TOUCH);
}
else
{
GOTO_EXIT(SYSINTR_NOP);
}
}
}
else
{
odo_tsr->odo_ioAdcCntr = TOUCH_Y_REQ;
GOTO_EXIT(SYSINTR_NOP);
}
}
else // check for UCB regInt
{
if ( (odo_tsr->odo_ucbStr & odo_regIntr) && (odo_tsr->odo_intrMask & odo_regIntrMask) )
{
odo_tsr->odo_ucbStr = odo_regIntr;
if ( odo_tsb->state == TCH_DO_SAMPLE )
{
odo_tsb->semaphore = 0;
my_odo_intrMask = odo_tsr->odo_intrMask;
my_odo_intrMask &= ~odo_regIntrMask;
my_odo_intrMask |= odo_penTimingIntrMask;
odo_tsr->odo_intrMask = my_odo_intrMask;
GOTO_EXIT(SYSINTR_NOP);
}
else
{
if ( (odo_tsr->odo_ucbRegister & odo_penState) != 0 )
{ // Pen Up
odo_tsr->odo_ioAdcCntr = 0;
odo_tsr->odo_ioAdcStr = odo_penTimingIntr;
odo_tsb->status = TOUCH_PEN_UP;
GOTO_EXIT(SYSINTR_TOUCH_CHANGED);
}
else
{ // Pen Down
odo_tsr->odo_intrMask |= odo_penIntrMask;
odo_tsb->coordCount = 0;
odo_tsr->odo_ioAdcCntr = TOUCH_X_REQ;
GOTO_EXIT(SYSINTR_NOP);
}
}
}
else // Pen input timer int
{
if ( (odo_tsr->odo_ioAdcStr & odo_penTimingIntr) && (odo_tsr->odo_intrMask & odo_penTimingIntrMask) )
{
odo_tsr->odo_ioAdcStr = odo_penTimingIntr;
if ( odo_tsb->semaphore == 0 )
{
odo_tsb->semaphore = 1;
my_odo_intrMask = odo_tsr->odo_intrMask;
my_odo_intrMask &= ~odo_penTimingIntrMask;
my_odo_intrMask |= odo_regIntrMask;
odo_tsr->odo_intrMask = my_odo_intrMask;
if ( odo_tsb->state == TCH_DO_BIAS )
{ // bias for pen up
odo_tsr->odo_ucbCntr = 0x0019;
odo_tsr->odo_ucbRegister = 0x00c3;
odo_tsb->state = TCH_DO_SAMPLE;
GOTO_EXIT(SYSINTR_NOP);
}
else
{
odo_tsr->odo_ucbCntr = 0x0009;
odo_tsr->odo_ucbRegister = 0x0000;
odo_tsb->state = TCH_DO_BIAS;
GOTO_EXIT(SYSINTR_NOP);
}
}
else // abort
{
GOTO_EXIT(SYSINTR_NOP);
}
}
else // touch UCB
{
if ( (odo_tsr->odo_ioAdcStr & odo_ucbIntr) && (odo_tsr->odo_intrMask & odo_ucbIntrMask) )
{
odo_tsr->odo_intrMask &= ~odo_ucbIntrMask;
odo_tsb->halPointer = (ULONG)odo_tsb->bufferA;
odo_tsb->state = TCH_DO_BIAS;
odo_tsb->status = TOUCH_PEN_DOWN;
GOTO_EXIT(SYSINTR_TOUCH_CHANGED);
}
else // Audio
{
if ( (odo_tsr->odo_ioSoundStr & odo_soundIntr) && (odo_tsr->odo_intrMask & odo_soundIntrMask) )
{
odo_tsr->odo_intrMask &= ~odo_soundIntrMask;
GOTO_EXIT(SYSINTR_AUDIO);
}
else
{
GOTO_EXIT(SYSINTR_NOP);
}
}
}
}
}
GOTO_EXIT(SYSINTR_NOP);
}
else if ( (my_odo_isr_reg & odo_prodSerialIntr) != 0 )
{
// mask the serial interrupt
odo_cpu->odo_cpuMr &= ~odo_prodSerialIntr;
GOTO_EXIT(SYSINTR_SERIAL);
}
else if ( (my_odo_isr_reg & odo_irIntr) != 0 )
{
// mask the ir interrupt
odo_cpu->odo_cpuMr &= ~odo_irIntr;
GOTO_EXIT(SYSINTR_IR);
}
else if ( (my_odo_isr_reg & odo_etherIntr) != 0 )
{
// mask the debug Ethernet interrupt
odo_cpu->odo_cpuMr &= ~odo_etherIntr;
GOTO_EXIT(SYSINTR_ETHER);
}
else if ( (my_odo_isr_reg & odo_keybIntr) != 0 )
{
// mask the keyboard interrupt
odo_cpu->odo_cpuMr &= ~odo_keybIntr;
GOTO_EXIT(SYSINTR_KEYBOARD);
}
else if ( (my_odo_isr_reg & odo_systemIntr) != 0 )
{
if ( (my_odo_csr_reg & pwrOffIntr) != 0 )
{
// mask the interupt
odo_cpu->odo_cpuMr &= ~pwrOffIntr;
// Tell keyboard driver that the off button was pressed.
((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->misc.offButton = 1;
GOTO_EXIT(SYSINTR_KEYBOARD);
}
else
{
//
// Check PCMCIA interrupt status
//
// Get Slot 0 enabled, pending interrupts
//
wPcmIntPending = odo_pci->odo_pcmciaIntrReg0 & (odo_pci->odo_pcmciaReg0 >> 3);
if ( (wPcmIntPending & odo_pcmciaIntr) != 0 )
{
//
// PCMCIA Slot 0 Interrupt. Mask the interrupt.
//
odo_pci->odo_pcmciaReg0 &= ~odo_pcmciaIntrMask;
GOTO_EXIT(SYSINTR_PCMCIA_LEVEL);
}
if ( (wPcmIntPending & odo_pcmciaStateIntr) != 0 )
{
//
// PCMCIA Slot 0 State change Interrupt
//
odo_pci->odo_pcmciaReg0 &= ~odo_pcmciaStateIntrMask;
odo_pci->odo_pcmciaIntrReg0 &= odo_pcmciaStateIntr; // R/W1C
GOTO_EXIT(SYSINTR_PCMCIA_STATE);
}
//
// Get Slot 1 enabled, pending interrupts
//
wPcmIntPending = odo_pci->odo_pcmciaIntrReg1 & (odo_pci->odo_pcmciaReg1 >> 3);
if ( (wPcmIntPending & odo_pcmciaIntr) != 0 )
{
//
// PCMCIA Slot 1 Interrupt. Mask the interrupt.
//
odo_pci->odo_pcmciaReg1 &= ~odo_pcmciaIntrMask;
GOTO_EXIT(SYSINTR_PCMCIA_LEVEL);
}
if ( (wPcmIntPending & odo_pcmciaStateIntr) != 0 )
{
//
// PCMCIA Slot 1 State change Interrupt
//
odo_pci->odo_pcmciaReg1 &= ~odo_pcmciaStateIntrMask;
odo_pci->odo_pcmciaIntrReg1 &= odo_pcmciaStateIntr; // R/W1C
GOTO_EXIT(SYSINTR_PCMCIA_STATE);
}
}
}
iRet = SYSINTR_NOP;
EXIT:
//
// Since all of the FPGA interrupts are multiplexed on one signal to the CPU
// we need to be careful when multiple interrupts are pending. We have
// cleared the interrupt at the CPU early on. If there's another interrupt
// that needs processing, we need to force a new interrupt. We do this by
// clearing the cpuMr register and reinstating it.
//
wMrTemp = odo_cpu->odo_cpuMr;
odo_cpu->odo_cpuMr = 0x0000;
odo_cpu->odo_cpuMr = wMrTemp;
return (iRet);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -