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

📄 keypad.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft 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) 2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
// File: keypad.c
//
// OEM Keypad routines for IPL on Freescale MX31 ADS hardware platform.
//
//------------------------------------------------------------------------------
#include "bsp.h"
#include "keys.h"

//------------------------------------------------------------------------------
// External Functions

//------------------------------------------------------------------------------
// External Variables

//------------------------------------------------------------------------------
// Defines
#define KPP_COLUMN_INUSE        8
#define KPP_ROW_INUSE           8
#define KPP_COLUMN_MASK         ((0x1 << KPP_COLUMN_INUSE) -1)
#define KPP_ROW_MASK            ((0x1 << KPP_ROW_INUSE) - 1)

//------------------------------------------------------------------------------
// Types
// Virtual key to bit mapping
typedef struct
{
    DWORD dwVk;
    DWORD dwBit;
} VKEY_TO_BIT;

//------------------------------------------------------------------------------
// Global Variables

//------------------------------------------------------------------------------
// Local Variables
static PCSP_KPP_REGS g_pKPP;
static PCSP_EPIT_REG g_pEPIT;

//------------------------------------------------------------------------------
// Local Functions

// 8x8 keypad matrix
static UINT8 keypadVK[] =
{
    //column 0
    0,
	VK_TSOFT1,      //SW11
	0,
	0,
	0,
	0,
	0,
	0,
	
    //column 1
    0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	
    //column 2
	0,
	0,
	0,
	0,
	0,
	0,
    0,
	0,

    //column 3
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,

    //column 4
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	
    //column 5
	VK_TSOFT2,      //SW3
    0,
	0,
	0,
	0,
	0,
	0,
    0,
	
    //column 6
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,

    //column 7
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
};

static const VKEY_TO_BIT sc_rgVkToBit[] = 
{
    { VK_TSOFT1,        KEY_TSOFT1 },
    { VK_TSOFT2,        KEY_TSOFT2 },
};

//------------------------------------------------------------------------------
//
// Function: EPITInit
//
// This function initializes EPIT module for msWait() in bspcmn\waitutils.c
//
// Parameters:
//      None.
//
//  Returns:
//      None.
//
//------------------------------------------------------------------------------
static void EPITInit(void)
{
	g_pEPIT = (PCSP_EPIT_REG) OALPAtoUA(CSP_BASE_REG_PA_EPIT1);
	if (g_pEPIT == NULL)
    {
        KITLOutputDebugString("EPITInit: EPIT1 null pointer!\r\n");
        return;
    }
    
    // Disable EPIT and clear all configuration bits
    OUTREG32(&g_pEPIT->CR, 0);

    // Assert software reset for the timer
    OUTREG32(&g_pEPIT->CR, CSP_BITFMASK(EPIT_CR_SWR));

    // Wait for the software reset to complete
    while (INREG32(&g_pEPIT->CR) & CSP_BITFMASK(EPIT_CR_SWR));

    // Enable timer for "free-running" mode where timer rolls
    // over from 0x00000000 to 0xFFFFFFFF
    OUTREG32(&g_pEPIT->CR,
        CSP_BITFVAL(EPIT_CR_EN, EPIT_CR_EN_ENABLE) |
        CSP_BITFVAL(EPIT_CR_ENMOD, EPIT_CR_ENMOD_RESUME) |
        CSP_BITFVAL(EPIT_CR_OCIEN, EPIT_CR_OCIEN_DISABLE) |
        CSP_BITFVAL(EPIT_CR_RLD, EPIT_CR_RLD_ROLLOVER) |
        CSP_BITFVAL(EPIT_CR_PRESCALAR, 0x20) | // divide by 32 to produce 1 ms tick
        CSP_BITFVAL(EPIT_CR_SWR, EPIT_CR_SWR_NORESET) |
        CSP_BITFVAL(EPIT_CR_IOVW, EPIT_CR_IOVW_NOOVR) |
        CSP_BITFVAL(EPIT_CR_DBGEN, EPIT_CR_DBGEN_ACTIVE) |
        CSP_BITFVAL(EPIT_CR_WAITEN, EPIT_CR_WAITEN_ENABLE) |
        CSP_BITFVAL(EPIT_CR_DOZEN, EPIT_CR_DOZEN_ENABLE) |
        CSP_BITFVAL(EPIT_CR_STOPEN, EPIT_CR_STOPEN_ENABLE) |
        CSP_BITFVAL(EPIT_CR_OM, EPIT_CR_OM_DICONNECT) |
        CSP_BITFVAL(EPIT_CR_CLKSRC, EPIT_CR_CLKSRC_CKIL)); // select 32khz clock as source
}

//------------------------------------------------------------------------------
//
// Function: msStall
//
// This function stalls system for time specified in milliseconds.
//
// Parameters:
//      nMilliseconds
//          [in] The milliseconds to stall system.
//
//  Returns:
//      None.
//
//------------------------------------------------------------------------------
static void msStall(unsigned nMilliseconds)
{
    UINT32 startCount, maxCount;
    
    if (g_pEPIT == NULL)
    {
        KITLOutputDebugString("msStall: ERROR - Timer not initialized\r\n");
        return;
    }  	
    
    startCount = EPIT_CNT_COUNT_MAX - INREG32(&g_pEPIT->CNT);
    maxCount = startCount + nMilliseconds;
    
    // wait for nMilliseconds number of ticks
    while((EPIT_CNT_COUNT_MAX - INREG32(&g_pEPIT->CNT)) < maxCount);
}

//------------------------------------------------------------------------------
//
// Function: KeypadSetClock
//
// This function enables or disables the clock of Keypad module.
//
// Parameters:
//      bEnable
//          [in] TRUE to enable KPP clock, otherwise disable it.
//
//  Returns:
//      None.
//
//------------------------------------------------------------------------------
static void KeypadSetClock(BOOL bEnable)
{
    PCSP_CCM_REGS pCCM = OALPAtoUA(CSP_BASE_REG_PA_CCM);

    if (bEnable)
    {
        // Enable KPP clock
        SETREG32(&pCCM->CGR[1], 0x3 << 20);
    }
    else
    {
        // Disable KPP clock
        CLRREG32(&pCCM->CGR[1], 0x3 << 20);
    }
}

//------------------------------------------------------------------------------
//
// Function: KeypadInit
//
// This function sets up the keypad module for IPL reading ULDR forcing key.
//
// Parameters:
//      None. 
//
//  Returns:
//      None.
//
//------------------------------------------------------------------------------
void KeypadInit(void)
{
    PCSP_IOMUX_REGS pIOMUX = OALPAtoUA(CSP_BASE_REG_PA_IOMUXC);

    // Configure IOMUX to request KPP pins
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_COL0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_COL1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_COL2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_COL3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_COL4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_COL5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_COL6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_COL7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_ROW0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_ROW1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_ROW2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_ROW3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_ROW4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_ROW5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_ROW6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(pIOMUX, DDK_IOMUX_PIN_KEY_ROW7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);

    // Enable KPP clock
    KeypadSetClock(TRUE);

    // Map KPP registers
    g_pKPP = OALPAtoUA(CSP_BASE_REG_PA_KPP);

    // Enable no. of rows in keypad (KRE = 1)
    // Configure columns as open-drain (KCO = 1)
    INSREG16BF(&g_pKPP->KPCR, KPP_KPCR_KRE, KPP_ROW_MASK);
    INSREG16BF(&g_pKPP->KPCR, KPP_KPCR_KCO, KPP_COLUMN_MASK);

    // Write 0's to all columns
    INSREG16BF(&g_pKPP->KPDR, KPP_KPDR_KCD, 0);

    // Configure rows as input, columns as output
    INSREG16BF(&g_pKPP->KDDR, KPP_KDDR_KCDD, KPP_COLUMN_MASK);
    INSREG16BF(&g_pKPP->KDDR, KPP_KDDR_KRDD, 0);

    // Clear KPKD and KPSR_KPKR status flag (w1c)
    // Clear synchronizer chain - KDSC (w1c)
    // Enable keypad interrupt - Set KDIE,
    // clear KRIE (avoid false release events)
    OUTREG16(&g_pKPP->KPSR,
        (CSP_BITFVAL(KPP_KPSR_KPP_EN, KPP_KPSR_KPP_EN_ENABLE) |
        CSP_BITFVAL(KPP_KPSR_KPKD, KPP_KPSR_KPKD_CLEAR) |
        CSP_BITFVAL(KPP_KPSR_KPKR, KPP_KPSR_KPKR_CLEAR) |
        CSP_BITFVAL(KPP_KPSR_KDSC, KPP_KPSR_KDSC_CLEAR) |
        CSP_BITFVAL(KPP_KPSR_KDIE, KPP_KPSR_KDIE_INT_ENABLE) |
        CSP_BITFVAL(KPP_KPSR_KRIE, KPP_KPSR_KRIE_INT_DISABLE)));

    // Disable KPP clock
    KeypadSetClock(FALSE);

    // Initialize EPIT for msStall()
    EPITInit();
}    

//------------------------------------------------------------------------------
//
// Function: FindBit
//
// This function finds the bit mask that corresponds to this virtual key.
//
// Parameters:
//      dwVk
//          [in] The virtual key.
//
//      rgVkToBit
//          [in] The virtual key to bit mapping table.
//
//      cVkToBit
//          [in] The size of the mapping table.
//
//  Returns:
//      The bit mask that corresponds to this virtual key.
//
//------------------------------------------------------------------------------
static DWORD FindBit(DWORD dwVk, const VKEY_TO_BIT *rgVkToBit, DWORD cVkToBit) 
{
    DWORD dwBit = 0;
    DWORD dwIdx;

    for (dwIdx = 0; dwIdx < cVkToBit; ++dwIdx)
    {
        const VKEY_TO_BIT *pVkToBit = &rgVkToBit[dwIdx];
        if (pVkToBit->dwVk == dwVk)
        {
            dwBit = pVkToBit->dwBit;
            break;
        }
    }

    return dwBit;
}

//------------------------------------------------------------------------------
//
// Function: KeypadRead
//
// This function returns a bit mask of the keys that are currently down.
//
// Parameters:
//      None. 
//
//  Returns:
//      The bit mask of the keys pressed.
//
//------------------------------------------------------------------------------
DWORD KeypadRead(void)
{
    UINT16 data[2][KPP_COLUMN_INUSE];
    DWORD ix;
    UINT16 ic, ir, ik;
    DWORD dwBits = 0;

    // Enable KPP clock
    KeypadSetClock(TRUE);

    //--------------------------------------------------------------
    // Read keypad physical state
    //--------------------------------------------------------------
    
    // Write '1' to all columns
    INSREG16BF(&g_pKPP->KPDR, KPP_KPDR_KCD, KPP_COLUMN_MASK);

    // Configure column as totem-pole outputs
    INSREG16BF(&g_pKPP->KPCR, KPP_KPCR_KCO, ~KPP_COLUMN_MASK);

    // Configure columns as open drain
    INSREG16BF(&g_pKPP->KPCR, KPP_KPCR_KCO, KPP_COLUMN_MASK);

    // Read all rows, we have to get same result twice
    ix = 0;
    do
    {
        // Wait debounce time on second and later meassures
        if (ix > 0) msStall(20);
        
        // Read all keypad columns
        for (ic = 0; ic < KPP_COLUMN_INUSE; ic++)
        {
            // Set column bit to zero
            INSREG16BF(&g_pKPP->KPDR, KPP_KPDR_KCD, ~(1 << ic));
            
            // Wait for outputs to settle
            msStall(1);
            
            // Get row status
            data[ix&1][ic] = EXTREG16BF(&g_pKPP->KPDR, KPP_KPDR_KRD);
        }
        
        // Write '1' to all columns
        INSREG16BF(&g_pKPP->KPDR, KPP_KPDR_KCD, KPP_COLUMN_MASK);
    } while (ix++ < 1 || memcmp(data[0], data[1], sizeof(data[0]) != 0));

    //--------------------------------------------------------------
    // Convert physical state to virtual keys state
    //--------------------------------------------------------------
    for (ic = 0, ik = 0; ic < KPP_COLUMN_INUSE; ic++)
    {
        // Find pressed virtual keys
        if ((data[0][ic] & KPP_ROW_MASK) == KPP_ROW_MASK)
        {
            ik += KPP_ROW_INUSE;
        }
        else for (ir = 0; ir < KPP_ROW_INUSE; ir++, ik++)
        {
            if ((data[0][ic] & (1 << ir)) == 0)
            {
                DWORD dwVk = keypadVK[ik];
                DWORD dwBit = FindBit(dwVk, sc_rgVkToBit, dimof(sc_rgVkToBit));
                dwBits |= dwBit;
                if (dwBit == 0)
                    KITLOutputDebugString("KeypadRead: No bit mask for key 0x%x\r\n", dwVk);
            }
        }
    }

    // Disable KPP clock
    KeypadSetClock(FALSE);

    return dwBits;
}

⌨️ 快捷键说明

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