📄 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.
//
#include <bsp.h>
#include "pmc_loader.h"
//------------------------------------------------------------------------------
// Defines
#define KPP_COLUMN_INUSE 8
#define KPP_ROW_INUSE 8
#define KEY_NUMBER (KPP_COLUMN_INUSE*KPP_ROW_INUSE)
#define KPP_COLUMN_MASK ((0x1<<KPP_COLUMN_INUSE) -1)
#define KPP_ROW_MASK ((0x1<<KPP_ROW_INUSE) - 1)
//------------------------------------------------------------------------------
// Local Variables
// 8x8 keypad matrix
UINT8 ScanCodeToVKeyTable[] =
{
//column 0
VK_RETURN, //SW60
0,
0,
0,
0,
0,
0,
0,
//column 1
VK_LEFT, //SW60
0,
0,
0,
0,
0,
0,
0,
//column 2
VK_DOWN, //SW60
VK_HOME, //SW9
0,
0,
0,
0,
0,
0,
//column 3
VK_RIGHT, //SW60
VK_F1, //SW8
0,
0,
0,
0,
0,
VK_RETURN, //SW56
//column 4
VK_UP, //SW60
VK_VOLUME_UP, //SW7
VK_VOLUME_DOWN,//SW15
0,
0,
0,
0,
VK_RETURN, //SW56
//column 5
0,
VK_F2, //SW6
0,
0,
0,
0,
0,
VK_BACK, //SW54
//column 6
0,
VK_F3, //SW5
0,
0,
0,
0,
0,
0,
//column 7
VK_BACK, //SW1
VK_F4, //SW4
0,
0,
0,
0,
0,
0,
};
static BOOL gfKeysPressed[0x100];
static int giKeysPressed;
static BOOL guiScanLast[KPP_ROW_INUSE * KPP_COLUMN_INUSE];
// i.MX31 registers
PCSP_KPP_REGS g_pKPP = NULL;
extern PCSP_CCM_REGS g_pCCM;
extern PCSP_IOMUX_REGS g_pIOMUX;
void KppIOMuxSettings(void)
{
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_COL0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_COL1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_COL2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_COL3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_COL4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_COL5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_COL6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_COL7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_ROW0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_ROW1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_ROW2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_ROW3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_ROW4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_ROW5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_ROW6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_KEY_ROW7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
}
void KppRegInit()
{
// Enable no. of rows in keypad (KRE = 1)
// Configure columns as open-drain (KCO = 1)
INSREG16(&g_pKPP->KPCR, CSP_BITFMASK(KPP_KPCR_KRE),
CSP_BITFVAL(KPP_KPCR_KRE, KPP_ROW_MASK));
INSREG16(&g_pKPP->KPCR, CSP_BITFMASK(KPP_KPCR_KCO),
CSP_BITFVAL(KPP_KPCR_KRE, KPP_COLUMN_MASK));
// Write 0's to all columns
INSREG16(&g_pKPP->KPDR, CSP_BITFMASK(KPP_KPDR_KCD),
CSP_BITFVAL(KPP_KPDR_KCD, 0));
// Configure rows as input, columns as output
INSREG16(&g_pKPP->KDDR, CSP_BITFMASK(KPP_KDDR_KCDD),
CSP_BITFVAL(KPP_KDDR_KCDD, KPP_COLUMN_MASK));
INSREG16(&g_pKPP->KDDR, CSP_BITFMASK(KPP_KDDR_KRDD),
CSP_BITFVAL(KPP_KDDR_KRDD, 0));
// Clear KPKD and KPSR_KPKR status flag (w1c)
// Clear synchronizer chain - KDSC (w1c)
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_DISABLE) |
CSP_BITFVAL(KPP_KPSR_KRIE, KPP_KPSR_KRIE_INT_DISABLE)));
}
// intialize platform hardware
void HwInit()
{
// map CCM memory space (clock control module)
g_pCCM = (PCSP_CCM_REGS) OALPAtoUA(CSP_BASE_REG_PA_CCM);
if(g_pCCM == NULL)
{
OALMSG(OAL_ERROR, (L"KppHwInit: CCM registers memory mapping failed!\r\n"));
return;
}
// Enable clock to Keypad -- bits 20-21 of CGR1
// Read in current value, "or" it with bits 20-21, write the value back to the register
OUTREG32( &g_pCCM->CGR[1], ((INREG32(&g_pCCM->CGR[1]) | 0x300000)) );
// map IOMux registers
g_pIOMUX = (PCSP_IOMUX_REGS) OALPAtoUA(CSP_BASE_REG_PA_IOMUXC);
if (g_pIOMUX == NULL)
{
OALMSG(OAL_ERROR, (L"KppHwInit: IOMux registers memory mapping failed!\r\n"));
return;
}
// IOMux settings for keypad pins
KppIOMuxSettings();
//map KPP memory space
g_pKPP = (PCSP_KPP_REGS) OALPAtoUA(CSP_BASE_REG_PA_KPP);
if(g_pKPP == NULL)
{
OALMSG(OAL_ERROR, (L"KppHwInit: Keypad registers memory mapping failed!\r\n"));
return;
}
// Initialize the Keypad port registers
KppRegInit();
}
// decode the keys pressed, record them in the array, and return # of keys pressed
UINT HwReadScanCode(BOOL keyPressed[])
{
UINT8 iCol, iColMask, iRow, iRowMask;
UINT numKeysPressed = 0;
UINT index;
// Write '1' to all columns
INSREG16(&g_pKPP->KPDR, CSP_BITFMASK(KPP_KPDR_KCD),
CSP_BITFVAL(KPP_KPDR_KCD, KPP_COLUMN_MASK));
// Configure column as totem-pole outputs
INSREG16(&g_pKPP->KPCR, CSP_BITFMASK(KPP_KPCR_KCO),
CSP_BITFVAL(KPP_KPCR_KCO, ~KPP_COLUMN_MASK));
// Configure columns as open drain
INSREG16(&g_pKPP->KPCR, CSP_BITFMASK(KPP_KPCR_KCO),
CSP_BITFVAL(KPP_KPCR_KCO, KPP_COLUMN_MASK));
// walk a zero across the columns of the matrix and read the rows
// to determine which key is pressed
for (iCol = 0, iColMask = 1; iCol < KPP_COLUMN_INUSE; iCol++, iColMask <<= 1)
{
// Write '0' for this column.
INSREG16(&g_pKPP->KPDR, CSP_BITFMASK(KPP_KPDR_KCD),
CSP_BITFVAL(KPP_KPDR_KCD, ~iColMask));
msWait(1);
for(iRow = 0, iRowMask = 1; iRow < KPP_ROW_INUSE; iRow++, iRowMask <<= 1)
{
index = iCol * KPP_ROW_INUSE + iRow;
// check if this row is low, then key pressed
if ( !(INREG16(&g_pKPP->KPDR) & iRowMask) )
{
keyPressed[index] = TRUE;
numKeysPressed++;
}
else
{
keyPressed[index] = FALSE;
}
}
}
// Done keypad scanning.
INSREG16(&g_pKPP->KPDR, CSP_BITFMASK(KPP_KPDR_KCD),
CSP_BITFVAL(KPP_KPDR_KCD, ~KPP_COLUMN_MASK));
INSREG16(&g_pKPP->KPCR, CSP_BITFMASK(KPP_KPCR_KCO),
CSP_BITFVAL(KPP_KPCR_KCO, KPP_COLUMN_MASK));
// Clear KPKD and KPKR status bits by writing a 1.
// Set the KPKR synchronizer chain by writing a 1 to KRSS.
// Clear the KPKD synchronizer chain by writing a 1 to KDSC.
OUTREG16(&g_pKPP->KPSR, CSP_BITFVAL(KPP_KPSR_KPP_EN, KPP_KPSR_KPP_EN_ENABLE) |
CSP_BITFVAL(KPP_KPSR_KRSS, KPP_KPSR_KRSS_SET) |
CSP_BITFVAL(KPP_KPSR_KPKR, KPP_KPSR_KPKR_CLEAR) |
CSP_BITFVAL(KPP_KPSR_KPKD, KPP_KPSR_KPKD_CLEAR) |
CSP_BITFVAL(KPP_KPSR_KDSC, KPP_KPSR_KDSC_CLEAR) );
//OALMSG(OAL_INFO, (L"Key code: %x\r\n", dwCode));
return numKeysPressed;
}
// this routine polls the keypad and returns TRUE if the currently pressed
// keys have changed
BOOL
KeypadPollKeys(void)
{
BOOL fChanged = FALSE;
BOOL scanAgain;
BOOL keyPressed[KPP_ROW_INUSE * KPP_COLUMN_INUSE];
BOOL keyPressed2[KPP_ROW_INUSE * KPP_COLUMN_INUSE];
UINT numKeysPressed, numKeysPressed2;
int timeout = 5;
UINT i;
// Debounce a little bit
do
{
scanAgain = FALSE;
numKeysPressed = HwReadScanCode(keyPressed);
msWait(30);
numKeysPressed2 = HwReadScanCode(keyPressed2);
if (numKeysPressed == numKeysPressed2)
{
for (i = 0; i < (KPP_ROW_INUSE * KPP_COLUMN_INUSE); i++)
{
// if the keys pressed are not the same, re-scan
if (keyPressed[i] != keyPressed2[i])
{
scanAgain = TRUE;
break;
}
}
}
// if number of keys pressed are not the same, scan again
else
scanAgain = TRUE;
} while ( (scanAgain) && (timeout-- > 0));
// check whether anything has changed
for (i = 0; i < (KPP_ROW_INUSE * KPP_COLUMN_INUSE); i++)
{
if (keyPressed[i] != guiScanLast[i])
{
fChanged = TRUE;
giKeysPressed = numKeysPressed;
// record the key status
guiScanLast[i] = keyPressed[i];
// update the global list of pressed keys
gfKeysPressed[ScanCodeToVKeyTable[i]] = keyPressed[i];
}
}
return fChanged;
}
int
KeypadGetNumKeysPressed(void)
{
return giKeysPressed;
}
BOOL
KeypadIsKeyPressed(UINT vkey)
{
return gfKeysPressed[vkey];
}
BOOL
KeypadInitialize(void)
{
int i;
for(i = 0; i < dim(gfKeysPressed); i++) {
gfKeysPressed[i] = FALSE;
}
for(i = 0; i < (KPP_ROW_INUSE * KPP_COLUMN_INUSE); i++)
{
guiScanLast[i] = FALSE;
}
giKeysPressed = 0;
// Initialize platform keypad hardware
HwInit();
// Cause us to enter the serial shell until we get the keypad driver completed.
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -