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

📄 keypad.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 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 + -