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

📄 keybdpdd.cpp

📁 wince.net板级支持包BSP for EP9315
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//**********************************************************************
//                                                                      
// Filename: keybdpdd.cpp
//                                                                      
// Description: Contains keyboard pdd routins.
//
// 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.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to 
// use this source code. For a copy of the EULA, please see the 
// LICENSE.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2002, All Rights Reserved                       
//                                                                      
//**********************************************************************

#include <windows.h>
#include <keybddr.h>
#include <nkintr.h>
#include <oalintr.h>
#include <hwdefs.h>
#include <keybdpdd.h>
#include <haluser.h>
#include "ps2key.h"


#include <LayMgr.h>
#include <keybdist.h>


static KEY_STATE_FLAGS  v_KeyStateToggled;
static HANDLE           ghInterrupt;

typedef volatile BYTE   *PVBYTE;
typedef volatile DWORD  *PVDWORD;
typedef volatile UINT32 *PVUINT32;
typedef volatile UINT16 *PVUINT16;


//
// Debug zones.
//
// #define ZONE_INIT       DEBUGZONE(0)
// #define ZONE_WARN       DEBUGZONE(14)
// #define ZONE_ERROR      DEBUGZONE(15)

//extern unsigned long gpKeyMap[8][8];

UINT            v_uiPddId;
PFN_KEYBD_EVENT v_pfnKeybdEvent;




//
// Function declarations.
//
void WINAPI EP931x_SPI_PS2_PowerHandler
(
    UINT uiPddId,
    BOOL fTurnOff
);
DWORD Ps2KeybdIsrThread(DWORD dwContext);
static void KeybdPowerOn( void );
static void KeybdPowerOff(void );





/*=============================================================================
           > PUBLIC DEFINITIONS INTENTED FOR USE BY THE MDD LAYER ONLY<
-----------------------------------------------------------------------------*/
extern "C" const DWORD gIntrKeyboard = SYSINTR_SPI;

BOOL WINAPI EP931x_SPI_PS2_Entry
(
    UINT uiPddId,
    PFN_KEYBD_EVENT pfnKeybdEvent,
    PKEYBD_PDD *ppKeybdPdd
);

PFN_KEYBD_PDD_ENTRY g_rgpfnPddEntries[] = 
{
    EP931x_SPI_PS2_Entry,
    NULL
};
 
//****************************************************************************
// KeybdPdd_PowerHandler
//****************************************************************************
//  @comm This routine runs in kernel context and assumes that interrupts are
//  disabled since it monkeys directly with registers.  It may not make any
//  system calls or cause a reschedule in any way.  You can read and write to
//  your own memory and that is about it.  If you put any subroutines inside
//  here, they must also follow this restriction.
// 
extern "C" 
void WINAPI KeybdPdd_PowerHandler
(
    BOOL    bOff            // @parm TRUE, the system is powering off; FALSE, the system is powering up.
)
{
    if (bOff) 
        KeybdPowerOff();
    else 
        KeybdPowerOn();

    return;
}


//****************************************************************************
// EP931x_SPI_PS2_Entry
//****************************************************************************
// 
// 
//
static KEYBD_PDD EP931xSPIPdd = 
{
    PS2_AT_PDD,
    _T("EP931x SPI"),
    EP931x_SPI_PS2_PowerHandler,
    NULL
};


BOOL WINAPI EP931x_SPI_PS2_Entry
(
    UINT uiPddId,
    PFN_KEYBD_EVENT pfnKeybdEvent,
    PKEYBD_PDD *ppKeybdPdd
)
{
    HANDLE  hthrd;

    //
    // There is only going to be one PDD keyboard.
    //
    v_uiPddId           = uiPddId;
    v_pfnKeybdEvent     = pfnKeybdEvent;
    *ppKeybdPdd         = &EP931xSPIPdd;


    //
    // The keyboard mdd should do this.
    //
    KeybdPowerOn();

    //
    // Creat the ISR process.
    //
    hthrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Ps2KeybdIsrThread, NULL, 0, NULL);

    //
    //  Since we don't need the handle, close it now.
    //
    CloseHandle(hthrd);


    return TRUE;
}


//****************************************************************************
// EP931x_SPI_PS2_PowerHandler
//****************************************************************************
// Power handler routine for the Windows CE 4.2 keyboard model.
// 
//
void WINAPI EP931x_SPI_PS2_PowerHandler
(
    UINT uiPddId,
    BOOL fTurnOff
)
{
    KeybdPdd_PowerHandler(fTurnOff);
}


//****************************************************************************
// KeybdPowerOn
//****************************************************************************
// Power on the keyboard.
// 
//
static void KeybdPowerOn( void )
{
    DEBUGMSG(ZONE_INIT,(TEXT("KeybdPowerOn")));
    volatile ULONG   ulTemp;
    ULONG   ulCount;

    //
    // Set GPIO pins 12 and 14 as outputs.  They are used in the ps2 keyboard 
    // interface.  
    //
    ulTemp           = *GPIO_PBDDR;
    *GPIO_PBDDR      = 0x50 | ulTemp;
    

    //
    // Clear GPIO pins 12 and 14.
    //    
    ulTemp           = *GPIO_PBDR;
    *GPIO_PBDR       = (~0x50) & ulTemp ;
    
    //
    // SPICR0_SPO - SCLKOUT Polarity
    // SPICR0_SPH - SCLKOUT Phase
    // Motorola format, 10 bit, one start, 8 data, one bit for parity, 
    // one stop bit.
    //
    *SPI_CR0        = SPICR0_SPO| SPICR0_SPH |SPICR0_FRF_MOTOROLA  | 
                      (SPICR0_DSS_MASK & (11 -1));
    
    //
    // Configure the device as a slave, enable interrupts and 
    // reset the device.
    //
    *SPI_CR1        = SPICR1_MS | SPICR1_RIE;
    *SPI_CR1        = SPICR1_MS | SPICR1_RIE | SPICR1_SSE;  

    Sleep(3);
    for(ulCount = 0; ulCount <32 ; ulCount++)
    {
        if(!(*SPI_SR & SPISR_RNE))
            break;
        ulTemp = *SPI_DR;
    }
    return;
}

//****************************************************************************
// KeybdPowerOff
//****************************************************************************
// Power off the keyboard
// 
//
static void KeybdPowerOff( void )
{
    DEBUGMSG(ZONE_INIT,(TEXT("KeybdPowerOff")));

    //GKBD_Enable(FALSE);
    //KBD_IRQ_OFF(g_pIrqBase);

    return;
}



//****************************************************************************
// KeybdPdd_InitializeDriver
//****************************************************************************
// On entry from the model device driver, the keyboard hardware is
// initialized.
// 
//
extern "C" 
BOOL WINAPI KeybdPdd_InitializeDriver
(
    PFN_KEYBD_EVENT_CALLBACK    pfnKeybdEventCallback   // @parm The callback into the input system.
)
{
    //TCHAR szText[64];

    DEBUGMSG(ZONE_INIT,(TEXT("KeybdPdd_InitializeDriver")));

    (*pfnKeybdEventCallback)(KEYBD_DEVICE_CONNECT,0);

    KeybdPowerOn();

    return (TRUE);
}


//****************************************************************************
// SPI2KScan
//****************************************************************************
// Get a character from the spi port if it is available.
// 
// Below is a picture of the spi signal from the PS2. 
//
//CK HHllllHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHHHLLLHllll
//DA HHHllllll000000111111222222333333444444555555666666777777ppppppssssssLLLLHHH
//        ^                                                                ^
//    start bit                                                   important bit
// 
//where:  l = 8042 driving the line 
//        L = KEYBOARD driving the line
//        1..7 data
//         = Parity 8042 driving
//        s = stop   8042 driving
//         = PARITY KEYBOARD driving the line
//        S = STOP   KEYBOARD driving the line
//
//  In our design the value comes high bit first and is inverted.  So we must
//  convert it to low byte first and then inverted it back.
//
static UCHAR SPI2KScan(ULONG ulSPIValue, PBOOL  pValid)
{
    UCHAR                   ucKScan = 0;
    ULONG                   ulParity;
    ULONG                   ulCount = 0;

    
    for(ulCount = 1, ulParity = 0 ; ulCount < 10; ulCount ++)
    {
        ulParity+= (ulSPIValue >> ulCount) & 0x1;
    }
    

    if(!(ulParity & 0x1)  && (ulSPIValue & 0x401) == 0x400)
    {

        *pValid = TRUE;
    
        //
        // Invert the pattern.
        //
        ulSPIValue =~ulSPIValue;
    
        //
        // Read in the value from the motorola spi file
        //
        ucKScan =  (UCHAR)((ulSPIValue & 0x004)<< 5);
        ucKScan |= (UCHAR)((ulSPIValue & 0x008)<< 3);
        ucKScan |= (UCHAR)((ulSPIValue & 0x010)<< 1);
        ucKScan |= (UCHAR)((ulSPIValue & 0x020)>> 1);
        ucKScan |= (UCHAR)((ulSPIValue & 0x040)>> 3);
        ucKScan |= (UCHAR)((ulSPIValue & 0x080)>> 5);
        ucKScan |= (UCHAR)((ulSPIValue & 0x100)>> 7);
        ucKScan |= (UCHAR)((ulSPIValue & 0x200)>> 9);
    }
    else
    {
        *pValid = FALSE;
    }
    
    return (ucKScan);        
}    

//****************************************************************************
// ExtendedVirtualKey
//****************************************************************************
// Converts an extended key to its virtual key code.
// 
//
static UINT32 ExtendedKscanVirtualKey(UCHAR ucExtendedKey)
{
    UINT32  uiVKey = 0;
    switch(ucExtendedKey)
    {
        case 0x11:  uiVKey = VK_RMENU;      break;
        case 0x14:  uiVKey = VK_RCONTROL;   break;
        case 0x1f:  uiVKey = VK_LWIN;       break;
        case 0x27:  uiVKey = VK_RWIN;       break;
        case 0x2f:  uiVKey = VK_APPS;       break;
        case 0x4a:  uiVKey = VK_DIVIDE;     break;
        case 0x5a:  uiVKey = VK_RETURN;     break;
        case 0x69:  uiVKey = VK_END;        break;
        case 0x6b:  uiVKey = VK_LEFT;       break;
        case 0x6c:  uiVKey = VK_HOME;       break;
        case 0x70:  uiVKey = VK_INSERT;     break;
        case 0x71:  uiVKey = VK_DELETE;     break;
        case 0x72:  uiVKey = VK_DOWN;       break;
        case 0x74:  uiVKey = VK_RIGHT;      break;
        case 0x75:  uiVKey = VK_UP;         break;
        case 0x7a:  uiVKey = VK_DOWN;       break; // Page Down
        case 0x7c:  uiVKey = VK_PRINT;      break;
        case 0x7d:  uiVKey = VK_UP;         break;  // Page Up.
        /* ignore escaped shift key */
        case 0x12:          
        default:
            uiVKey = 0;
            break;
    }
    return (uiVKey);
}


//****************************************************************************
// KeybdPdd_GetEvent
//****************************************************************************
//  Called by the MDD to retrieve keyboard events after SYSINTR_KEYBD is 
//  signalled.
//
extern "C" INT WINAPI 
KeybdPdd_GetEvent
(
    UINT32 VirtualKeys[16], //  @parm Buffer to put virtual keys which were detected.
    KEY_STATE_FLAGS KeyEvents[16]       //  @parm Buffer to put key state flags.
)
{
    static  unsigned char   ucKScan[4] = {0,0,0,0};
    //static    unsigned char   bParity[4] = {0,0,0,0};
    static  unsigned int    ulNum = 0;
    INT     iVKeysReturned = 0;
    UINT32  uiVKey;
    ULONG   ulTemp;
    BOOL    bParityValid;
    

    //
    // Set GPIO pins 14 high.  This causes spiclk to be low and prevent the keyboard from sending keys.
    // The keyboard is disabled while reading in the keys.
    //
    // DEBUGMSG(1,(L"GetEvent_Enter\n"));
    HalWriteCommonReg(GPIO_PBDR, 0x40, 0x40);


    while((*SPI_SR & SPISR_RNE ) &&  iVKeysReturned<16)
    {
        ulTemp = *SPI_DR;

        //
        // Read in the value from the SPI controller.
        //
        ucKScan[ulNum++] = SPI2KScan(ulTemp, &bParityValid);


        // DEBUGMSG(1,(L"0x%3x 0x%01x\n",ulTemp, bParityValid));

        //
        // Reset the SPI device and break.
        //
        if(!bParityValid)
        {
            ulNum = 0;
            break;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -