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

📄 bspkeypad.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    0,                  // Scan Code 0xE05B
    0,                  // Scan Code 0xE05C
    0,                  // Scan Code 0xE05D
    0,                  // Scan Code 0xE05E
    0,                  // Scan Code 0xE05F
    0,                  // Scan Code 0xE060
    0,                  // Scan Code 0xE061
    0,                  // Scan Code 0xE062
    0,                  // Scan Code 0xE063
    0,                  // Scan Code 0xE064
    0,                  // Scan Code 0xE065
    0,                  // Scan Code 0xE066
    0,                  // Scan Code 0xE067
    0,                  // Scan Code 0xE068
    VK_END,             // Scan Code 0xE069
    0,                  // Scan Code 0xE06A
    VK_LEFT,            // Scan Code 0xE06B
    VK_HOME,            // Scan Code 0xE06C
    0,                  // Scan Code 0xE06D
    0,                  // Scan Code 0xE06E
    0,                  // Scan Code 0xE06F
    VK_INSERT,          // Scan Code 0xE070
    VK_DELETE,          // Scan Code 0xE071
    VK_DOWN,            // Scan Code 0xE072
    0,                  // Scan Code 0xE073
    VK_RIGHT,           // Scan Code 0xE074
    VK_UP,              // Scan Code 0xE075
    0,                  // Scan Code 0xE076
    0,                  // Scan Code 0xE077
    0,                  // Scan Code 0xE078
    0,                  // Scan Code 0xE079
    VK_NEXT,            // Scan Code 0xE07A
    0,                  // Scan Code 0xE07B
    VK_SNAPSHOT,        // Scan Code 0xE07C
    VK_PRIOR,           // Scan Code 0xE07D
    VK_CANCEL,          // Scan Code 0xE07E
    0,                  // Scan Code 0xE07F
};

static ScanCodeToVKeyData scvkEngUS =
{
    0,
    ScanCodeTableFirst,
    ScanCodeTableLast,
    ScanCodeToVKeyTable
};

static ScanCodeToVKeyData scvkE0EngUS =
{
    0xE000,
    E0ScanCodeTableFirst,
    E0ScanCodeTableLast,
    E0ScanCodeToVKeyTable
};

static ScanCodeToVKeyData *rgscvkKPPEngUSTables[] =
{
    &scvkEngUS, &scvkE0EngUS
};

// There is currently no Key Remapping being performed.
// If key remapping is needed, this structure definition
// will need to be moved down below the Remap function.
static DEVICE_LAYOUT dlKPPEngUs =
{
    sizeof(DEVICE_LAYOUT),
    KPP_PDD,
    rgscvkKPPEngUSTables,
    dim(rgscvkKPPEngUSTables),
    NULL, //KPPUsRemapVKey,
};

//------------------------------------------------------------------------------
// Local Functions
BOOL BSPKppSetClockGatingMode(BOOL startClocks);
static UINT KppScanSequence(UINT32 rguiScanCode[16], BOOL rgfKeyUp[16], BOOL allowSysCalls);
static void KppRestoreRegState();
static void KppSaveRegState();
static void KppBusyWait(DWORD waitTime);

//------------------------------------------------------------------------------
//
// Function: KPPUsRemapVKey
//
// Remapping function for the keypad.  Called from the layout manager.
// Returns the number of remapped events placed in pRmpKbdEvents
// Call with pRmpKbdEvents == NULL anc cMaxRmpKbdEvents == 0 to get the
// maximum size necessary for pRmpKbdEvents buffer.
//
// Parameters:
//      pKbdEvents -
//          [in] List of events to remap.
//
//      cKbdEvents -
//          [in] Count of events in pKbdEvents
//
//      pRmpKbdEvents -
//          [out] Buffer where remapped events will be placed
//
//      cMaxRmpKbdEvents -
//          [in] Maximum number of remapped events
//
// Returns:
//      The number of remapped events.
//
//------------------------------------------------------------------------------
static UINT WINAPI KPPUsRemapVKey(
    const KEYBD_EVENT *pKbdEvents,
    UINT               cKbdEvents,
    KEYBD_EVENT       *pRmpKbdEvents,
    UINT               cMaxRmpKbdEvents
    )
{
    static BOOL fFnDown = FALSE;
    UINT cRmpKbdEvents = 0;

    SETFNAME(_T("KPPUsRemapVKey"));

    DEBUGMSG(ZONE_FUNCTION, (TEXT("++%s\r\n"), pszFname));

    if (pRmpKbdEvents == NULL)
    {
        // 1 to 1 mapping
        DEBUGCHK(cMaxRmpKbdEvents == 0);
        return cKbdEvents;
    }

    DEBUGCHK(pKbdEvents != NULL);

    if (cMaxRmpKbdEvents < cKbdEvents)
    {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Buffer is not large enough!\r\n"),
            pszFname));
        return 0;
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("--%s\r\n"), pszFname));

    return cRmpKbdEvents;
}


//------------------------------------------------------------------------------
//
// Function: KPPLayout
//
// This function initializes the device layout for the EVB keypad.
//
// Parameters:
//      None.
//
// Returns:
//      TRUE if success, FALSE if failure.
//
//------------------------------------------------------------------------------
extern "C" BOOL KPPLayout(PDEVICE_LAYOUT pDeviceLayout)
{
    BOOL fRet = FALSE;

    DEBUGCHK(pDeviceLayout != NULL);

    if (pDeviceLayout->dwSize != sizeof(DEVICE_LAYOUT))
    {
        RETAILMSG(1, (_T("KPPLayout: data structure size mismatch\r\n")));
        goto Leave;
    }

    // Make sure that the Sc->Vk tables are the sizes that we expect
    DEBUGCHK(dim(ScanCodeToVKeyTable) == (1 + ScanCodeTableLast - ScanCodeTableFirst));

    *pDeviceLayout = dlKPPEngUs;

    fRet = TRUE;

Leave:
    return fRet;
}
#ifdef DEBUG
// Verify function declaration against the typedef.
static PFN_DEVICE_LAYOUT_ENTRY v_pfnDeviceLayout = KPPLayout;
#endif


//------------------------------------------------------------------------------
//
// Function: BSPKppRegInit
//
// Initializes the keypad port registers.
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void BSPKppRegInit()
{
    KPP_FUNCTION_ENTRY();

    // Enable KPP clocks to access KPP registers
    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);
    }

    // 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] = IntermediateScanCode[index];
                            rgfKeyUp[evCnt] = TRUE;
                            evCnt++;
                            keyDown[iCol] &= ~iRowMask;
                            keyDownSent[index] = FALSE;				

⌨️ 快捷键说明

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