?? keypad.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 + -