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

📄 bspkeypad.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    BSPKppSetClockGatingMode(TRUE);

    // 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)
    // 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)));

    DEBUGMSG(ZONE_PDD, (TEXT("End of Init method - ctrl: %x  status: %x  direction: %x data: %x\r\n"),
                    g_pKPP->KPCR, g_pKPP->KPSR, g_pKPP->KDDR, g_pKPP->KPDR));

    // Disable KPP clocks for Power Management
    BSPKppSetClockGatingMode(FALSE);

    KPP_FUNCTION_EXIT();
}

//------------------------------------------------------------------------------
//
// Function: BSPKPPGetScanCodes
//
// This function gets the scan codes and key events from the KPP.
//
// Parameters:
//      rguiScanCode[16] -
//          [out] An array of scan codes for each key event detected.
//
//      rgfKeyUp[16] -
//          [out] An array of booleans telling, for each key event,
//          whether the key has gone up or down.
//
// Returns:
//      The number of key events.
//
//------------------------------------------------------------------------------

UINT BSPKPPGetScanCodes(UINT32 rguiScanCode[16], BOOL rgfKeyUp[16])
{
    UINT eventCount;

    KPP_FUNCTION_ENTRY();

    // Enable KPP clocks to access registers
    // during key scan sequence
    BSPKppSetClockGatingMode(TRUE);

    KppSaveRegState();

    eventCount = KppScanSequence(rguiScanCode, rgfKeyUp, TRUE);

    if (g_SysSuspend)
    {
        KppRestoreRegState();

        g_SysSuspend = FALSE;

        // Call scan sequence again with restored KPP register
        // state to assure that we read the correct scan codes.
        eventCount = KppScanSequence(rguiScanCode, rgfKeyUp, TRUE);
    }

//ajust the response for 5-d button
#define LEFTINDEX 54
#define DOWNINDEX 46
#define RIGHTINDEX 38
#define UPINDEX 30
    
    if(eventCount >= 1)
    {
        if(keyDownSent[RIGHTINDEX]&&keyDownSent[UPINDEX])    rguiScanCode[0] = UPINDEX;    
        else if(keyDownSent[RIGHTINDEX])    rguiScanCode[0] = RIGHTINDEX;
        else if(keyDownSent[DOWNINDEX])    rguiScanCode[0] = DOWNINDEX;
        else if(keyDownSent[LEFTINDEX])    rguiScanCode[0] = LEFTINDEX;
        else if(keyDownSent[UPINDEX])    rguiScanCode[0] = UPINDEX;
        eventCount = 1;
    }

#if 0
    //hold key
    #define HOLDINDEX    (1 * KPP_ROW_INUSE + 2)
    UINT i;
    if((keyDownSent[HOLDINDEX]==TRUE)&&(eventCount != 0)){  //change any key action to hold message
        rguiScanCode[0]=HOLDINDEX;
        rgfKeyUp[0]=FALSE;
        eventCount = 1;
    }
    else{
        for(i=0; i<eventCount; i++)
        {
            if((rguiScanCode[i]==HOLDINDEX)&&(rgfKeyUp[i]==TRUE)){
                rguiScanCode[0]=HOLDINDEX;
                rgfKeyUp[0]=TRUE;
                eventCount = 1;
                break;    
            }
        }    
    }
#endif

    // Disable KPP clocks for Power Management
    BSPKppSetClockGatingMode(FALSE);

    // Wait, so that we do not immediately trigger another keypad
    // interrupt upon completing the scan sequence and returning
    // the scan codes.
    Sleep(9);

    KPP_FUNCTION_EXIT();

    return eventCount;
}    


//------------------------------------------------------------------------------
//
// Function: KppScanSequence
//
// This function scans the keypad matrix, compiling a list of key events.
//
// Parameters:
//      rguiScanCode[16] -
//          [out] An array of scan codes for each key event detected.
//
//      rgfKeyUp[16] -
//          [out] An array of booleans telling, for each key event,
//          whether the key has gone up or down.
//
//      allowSysCalls -
//          [in] A boolean variable telling us whether or not we can
//          make system calls.  This is needed for the case when we are
//          entering suspend and cannot make system calls.
//
// Returns:
//      The number of key events.
//
//------------------------------------------------------------------------------
static UINT KppScanSequence(UINT32 rguiScanCode[16], BOOL rgfKeyUp[16], BOOL allowSysCalls)
{
    static BOOL notInitialized = TRUE;  // Set to false after initialization.
    static CRITICAL_SECTION g_hKppLock;
    UINT16 tempKPSR; // KPSR value read at start of scan sequence
    UINT16 kpsrWrVal = 0;
    UINT8 iRowMask;
    UINT8 iColMask;
    UINT8 iCol;
    UINT8 iRow;
    UINT8 evCnt = 0;
    UINT8 index;
    UINT8 rowData;
    BOOL  isKeyDown = FALSE;

    KPP_FUNCTION_ENTRY();

    // Initialize variables the first time this method is called
    if (notInitialized)
    {
        // Do not execute initialization again
        notInitialized = FALSE;

        // create KPP critical section
        InitializeCriticalSection(&g_hKppLock);

        // Initialise key status to all release '1' and clear key down status.
        memset(kppStatus, KPP_ROW_MASK, sizeof(kppStatus));
        memset(keyDown, 0, sizeof(keyDown));
        memset(prevDownTime, 0, sizeof(prevDownTime));
        memset(keyDownSent, 0, sizeof(keyDownSent));
    }

    if (allowSysCalls)
    {
        EnterCriticalSection(&g_hKppLock);
    }

    // Read keypad status register
    tempKPSR = INREG16(&g_pKPP->KPSR);

    DEBUGMSG(ZONE_PDD, (TEXT("Before scan, tempKPSR 0x%04x, KPSR 0x%04x. \r\n"), 
        tempKPSR, INREG16(&g_pKPP->KPSR)));

    // Disable interrupts while processing.
    INSREG16(&g_pKPP->KPSR, CSP_BITFMASK(KPP_KPSR_KDIE),
        CSP_BITFVAL(KPP_KPSR_KDIE, KPP_KPSR_KDIE_INT_DISABLE));
    INSREG16(&g_pKPP->KPSR, CSP_BITFMASK(KPP_KPSR_KRIE),
        CSP_BITFVAL(KPP_KPSR_KRIE, KPP_KPSR_KRIE_INT_DISABLE));

    if(CSP_BITFEXT(tempKPSR, KPP_KPSR_KPKD) && CSP_BITFEXT(tempKPSR, KPP_KPSR_KDIE))
    {
        // At least 1 key depressed
        DEBUGMSG(ZONE_PDD, 
            (TEXT("Depress interrupt, KPSR 0x%04x. \r\n"), tempKPSR));

        // 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));

        // Scan key map for changes
        for(iCol = 0, iColMask = 1; iCol < KPP_COLUMN_INUSE  && !g_SysSuspend; iCol++, iColMask <<= 1)
        {
            // Write '0' for this column.
            INSREG16(&g_pKPP->KPDR, CSP_BITFMASK(KPP_KPDR_KCD),
                CSP_BITFVAL(KPP_KPDR_KCD, ~iColMask));
            // Wait required to allow row outputs to propagate
            if (allowSysCalls)
            {
                Sleep(1);
            }
            else
            {
                KppBusyWait(1);
            }

            // Get current key status & handle accordingly
            rowData = KPP_ROW_MASK & EXTREG16(&g_pKPP->KPDR,
                CSP_BITFMASK(KPP_KPDR_KRD), KPP_KPDR_KRD_LSH);

            for(iRow = 0, iRowMask = 1; iRow < KPP_ROW_INUSE && !g_SysSuspend; iRow++, iRowMask <<= 1)
            {
                if((rowData & iRowMask) ^ (kppStatus[iCol] & iRowMask))
                {
                    // Key status changed. Send event accordingly.
                    index = iCol * KPP_ROW_INUSE + iRow;

                    if((rowData & iRowMask))
                    {
                        // Key status changed to released.
                        // Handle briefly pressed keys.
                        if(!(kppStatus[iCol] & iRowMask) && !(keyDown[iCol] & iRowMask))
                        {
                            // Key depressed very briefly, less than 1 debounce period.
                            DEBUGMSG(ZONE_PDD, (TEXT("Changed: depressed < 1 period.\r\n")));
                        }
                        else 
                        {
                            rguiScanCode[evCnt] = index;
                            rgfKeyUp[evCnt] = TRUE;
                            evCnt++;
                            keyDown[iCol] &= ~iRowMask;
                            keyDownSent[index] = FALSE;

                            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;
                        }
                // *2 changed by loren to avoid glitch
                        if((GetTickCount() - prevDownTime[index]) >= KEY_DEBOUNCE_PERIOD *2)
                        {

                            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] = 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

⌨️ 快捷键说明

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