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

📄 bspkeypad.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:

                            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 + -