📄 bspkeypad.cpp
字号:
DEBUGMSG(ZONE_PDD,
(TEXT("Key released, tempKPSR 0x%04x, KPSR 0x%04x. \r\n"),
tempKPSR, INREG16(&g_pKPP->KPSR)));
}
}
else
{
// Key status changed to depressed.
isKeyDown = TRUE;
DEBUGMSG(ZONE_PDD,
(TEXT("Key pressed, tempKPSR 0x%04x, KPSR 0x%04x. \r\n"),
tempKPSR, INREG16(&g_pKPP->KPSR)));
prevDownTime[index] = GetTickCount();
}
}
else // No key status change
{
if(!(rowData & iRowMask))
{
// Key still depressed.
// Send key down event after debouncing period.
isKeyDown = TRUE;
index = iCol * KPP_ROW_INUSE + iRow;
if(GetTickCount() < prevDownTime[index])
{
prevDownTime[index] = 0;
}
if((GetTickCount() - prevDownTime[index]) >= KEY_DEBOUNCE_PERIOD)
{
if(!(keyDown[iCol] & iRowMask))
{
keyDown[iCol] |= iRowMask;
}
DEBUGMSG(ZONE_PDD,
(TEXT("Keypress debounced. \r\n")));
if (!keyDownSent[index])
{
// Key down not yet sent, so process
rguiScanCode[evCnt] = IntermediateScanCode[index];
rgfKeyUp[evCnt] = FALSE;
evCnt++;
keyDownSent[index] = TRUE;
}
}
}
}
}
// Store current keypad status
kppStatus[iCol] = rowData;
}
// 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.
// Re-enable KDIE and KRIE to detect key hold and key release events.
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) |
CSP_BITFVAL(KPP_KPSR_KDIE, KPP_KPSR_KDIE_INT_ENABLE) |
CSP_BITFVAL(KPP_KPSR_KRIE, KPP_KPSR_KRIE_INT_ENABLE));
}
else if(CSP_BITFEXT(tempKPSR, KPP_KPSR_KPKR) && CSP_BITFEXT(tempKPSR, KPP_KPSR_KRIE))
{
DEBUGMSG(ZONE_PDD,
(TEXT("Release interrupt, KPSR 0x%04x. \r\n"), tempKPSR));
// All configured keys released. Reset all key indicators
// and send key up event for all keys marked as down.
for(iCol = 0; iCol < KPP_COLUMN_INUSE && !g_SysSuspend; iCol++)
{
for(iRow = 0, iRowMask = 1; iRow < KPP_ROW_INUSE && !g_SysSuspend; iRow++, iRowMask <<= 1)
{
index = iCol * KPP_ROW_INUSE + iRow;
if(keyDown[iCol] & iRowMask)
{
// Handle keys marked as down.
rguiScanCode[evCnt] = IntermediateScanCode[index];
rgfKeyUp[evCnt] = TRUE;
evCnt++;
keyDownSent[index] = FALSE;
}
else
{
// Take care of keys that are
// depressed only very briefly.
if(!(kppStatus[iCol] & iRowMask))
{
// Key depressed very briefly, less
// than 1 debounce period.
DEBUGMSG(ZONE_PDD,
(TEXT("Keys depressed < 1 period.\r\n")));
}
}
}
// Clear indicators.
keyDown[iCol] = (UINT8) ~KPP_ROW_MASK;
kppStatus[iCol] = KPP_ROW_MASK;
}
// Disable key release interrupts and re-enable key depress interrupts.
OUTREG16(&g_pKPP->KPSR,
(CSP_BITFVAL(KPP_KPSR_KPP_EN, KPP_KPSR_KPP_EN_ENABLE) |
CSP_BITFVAL(KPP_KPSR_KDIE, KPP_KPSR_KDIE_INT_ENABLE) |
CSP_BITFVAL(KPP_KPSR_KRIE, KPP_KPSR_KRIE_INT_DISABLE) |
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)));
}
else
{
OUTREG16(&g_pKPP->KPSR,
(CSP_BITFVAL(KPP_KPSR_KPP_EN, KPP_KPSR_KPP_EN_ENABLE) |
CSP_BITFVAL(KPP_KPSR_KDIE, KPP_KPSR_KDIE_INT_ENABLE) |
CSP_BITFVAL(KPP_KPSR_KRIE, KPP_KPSR_KRIE_INT_DISABLE) |
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)));
}
DEBUGMSG(ZONE_PDD, (TEXT("Scan sequence completed\r\n")));
if (allowSysCalls)
{
LeaveCriticalSection(&g_hKppLock);
}
if (evCnt > MAX_KEY_EVENTS)
{
evCnt = MAX_KEY_EVENTS;
}
KPP_FUNCTION_EXIT();
return evCnt;
}
//------------------------------------------------------------------------------
//
// Function: BSPKppPowerOn
//
// Power on the keypad.
//
// Parameters:
// None.
//
// Returns:
// TRUE if success, FALSE if failure.
//
//------------------------------------------------------------------------------
BOOL BSPKppPowerOn()
{
UINT16 kpsr;
KPP_FUNCTION_ENTRY();
// Configure IOMUX to request KPP pins
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
BSPKppRegInit();
// Enable KPP clocks to access KPP registers
BSPKppSetClockGatingMode(TRUE);
// Until keypad does not report key-down/key-up event
do
{
// Wait ~10ms
KppBusyWait(10);
// Get current status
kpsr = INREG16(&g_pKPP->KPSR);
// Clear status bits
OUTREG16(&g_pKPP->KPSR, (kpsr | CSP_BITFMASK(KPP_KPSR_KPKD)));
}while (kpsr & CSP_BITFMASK(KPP_KPSR_KPKD));
if (!g_bRestoreClocks)
{
// Disable KPP clocks for Power Management
BSPKppSetClockGatingMode(FALSE);
}
KPP_FUNCTION_EXIT();
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: BSPKppPowerOff
//
// Power off the keypad.
//
// Parameters:
// None.
//
// Returns:
// TRUE if success, FALSE if failure.
//
//------------------------------------------------------------------------------
BOOL BSPKppPowerOff()
{
UINT16 kpsr;
DDK_CLOCK_GATE_MODE lastKPPClockMode;
KPP_FUNCTION_ENTRY();
// Tell the IST we are entering suspend state
g_SysSuspend = TRUE;
// Get current KPP clock mode
DDKClockGetGatingMode(DDK_CLOCK_GATE_INDEX_KPP, &lastKPPClockMode);
if (lastKPPClockMode == DDK_CLOCK_GATE_MODE_ENABLED_ALL)
{
g_bRestoreClocks = TRUE;
}
else
{
g_bRestoreClocks = FALSE;
}
BSPKppRegInit(); // Clears KPKD and KPKR
// Enable KPP clocks to access KPP registers
BSPKppSetClockGatingMode(TRUE);
// Until keypad does not report key-down/key-up event
do
{
// Wait ~10ms
KppBusyWait(10);
// Get current status
kpsr = INREG16(&g_pKPP->KPSR);
// Clear status bits
OUTREG16(&g_pKPP->KPSR, (kpsr | CSP_BITFMASK(KPP_KPSR_KPKD)));
}while (kpsr & CSP_BITFMASK(KPP_KPSR_KPKD));
// Disable KPP clocks for Power Management
BSPKppSetClockGatingMode(FALSE);
// Configure IOMUX to release KPP pins. Only release pins if KPP is not
// being used as wake source.
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL0, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL1, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL2, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL3, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL4, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL5, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL6, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_COL7, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW0, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW1, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW2, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW3, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW4, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW5, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW6, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_KEY_ROW7, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_NONE);
KPP_FUNCTION_EXIT();
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: BSPKppSetClockGatingMode
//
// Turn on/off clocks to the keypad port module.
//
// Parameters:
// startClocks
// [in] If TRUE, turn clocks to KPP on.
// If FALSE, turn clocks to KPP off
//
// Returns:
// TRUE if success, FALSE if failure.
//
//------------------------------------------------------------------------------
BOOL BSPKppSetClockGatingMode(BOOL startClocks)
{
if (startClocks)
{
// Turn KPP clocks on
if (!DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_KPP,
DDK_CLOCK_GATE_MODE_ENABLED_ALL))
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s: Failed to set CRM clock gating mode!\r\n"), __WFUNCTION__));
return FALSE;
}
}
else
{
// Turn KPP clocks off
if (!DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_KPP,
DDK_CLOCK_GATE_MODE_DISABLED))
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s: Failed to set CRM clock gating mode!\r\n"), __WFUNCTION__));
return FALSE;
}
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: KppSaveRegState
//
// Saves the state of KPP registers, in case the system changes to
// the suspend state during the key scan sequence.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
static void KppSaveRegState()
{
g_wKPSRStored = INREG16(&g_pKPP->KPSR);
memcpy(keyDownStored, keyDown, KPP_COLUMN_INUSE);
memcpy(prevDownTimeStored, prevDownTime, sizeof(prevDownTimeStored));
memcpy(keyDownSentStored, keyDownSent, sizeof(keyDownSentStored));
memcpy(kppStatusStored, kppStatus, KPP_COLUMN_INUSE);
}
//------------------------------------------------------------------------------
//
// Function: KppRestoreRegState
//
// Restores the state of KPP registers, for when the system returns from
// the suspend state during the key scan sequence.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
static void KppRestoreRegState()
{
memcpy(keyDown, keyDownStored, KPP_COLUMN_INUSE);
memcpy(prevDownTime, prevDownTimeStored, KEY_NUMBER * sizeof(UINT32));
memcpy(keyDownSent, keyDownSentStored, KEY_NUMBER * sizeof(BOOL));
memcpy(kppStatus, kppStatusStored, KPP_COLUMN_INUSE);
// Restore interrupts to their pre-suspend state,
// and clear status registers.
OUTREG16(&g_pKPP->KPSR,
(CSP_BITFVAL(KPP_KPSR_KPP_EN, CSP_BITFEXT(g_wKPSRStored, KPP_KPSR_KPP_EN)) |
CSP_BITFVAL(KPP_KPSR_KDIE, CSP_BITFEXT(g_wKPSRStored, KPP_KPSR_KDIE)) |
CSP_BITFVAL(KPP_KPSR_KRIE, CSP_BITFEXT(g_wKPSRStored, KPP_KPSR_KRIE)) |
CSP_BITFVAL(KPP_KPSR_KPKD, KPP_KPSR_KPKD_CLEAR) |
CSP_BITFVAL(KPP_KPSR_KPKR, KPP_KPSR_KPKR_CLEAR) |
CSP_BITFVAL(KPP_KPSR_KRSS, KPP_KPSR_KRSS_SET) |
CSP_BITFVAL(KPP_KPSR_KDSC, KPP_KPSR_KDSC_CLEAR)));
// Wait 1 ms for sychronizer chain to clear
Sleep(1);
}
//------------------------------------------------------------------------------
//
// Function: KppBusyWait
//
// Uses GetTickCount to wait.
//
// Parameters:
// waitTime
// [in] Time to wait in milliseconds.
//
// Returns:
// None.
//
//------------------------------------------------------------------------------
static void KppBusyWait(DWORD waitTime)
{
DWORD startTime, currentTime, realWaitTime;
realWaitTime = waitTime + 1;
// Wait for 10 ms, then check KPKD again
startTime = GetTickCount();
do
{
currentTime = GetTickCount();
if (currentTime < startTime)
{
startTime = currentTime;
}
} while(currentTime - startTime < realWaitTime);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -