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

📄 armint.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 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 + -