www.pudn.com > Bit1611_demo_code.rar > KEY.C


/* ********************************************************************** 
 
         Copyright (c) 2002-2006 Beyond Innovation Technology Co., Ltd 
 
        All rights are reserved. Reproduction in whole or in parts is 
    prohibited without the prior written consent of the copyright owner. 
   ---------------------------------------------------------------------- 
 
    Module: KEY.C - Keypad. 
 
    Purpose: Implementation of KEY module. 
 
    Version: 0.01                                   11:35AM  2005/11/17 
 
    Compiler: Keil 8051 C Compiler v8.01 
 
    Reference: 
 
   ---------------------------------------------------------------------- 
    Modification: 
 
    R0.01 11:35AM  2005/11/17 Jeffrey Chang 
    Reason: 
        1. Original. 
    Solution: 
 
   ********************************************************************** */ 
 
#define _KEY_C_ 
 
/* ------------------------------------ 
    Header Files 
   ------------------------------------ */ 
#include "key.h" 
 
 
/* :::::::::::::::::::::::::::::::::::: 
    Key scanning states 
   :::::::::::::::::::::::::::::::::::: */ 
#define KEY_STATE_UP                    1 
#define KEY_STATE_DEBOUNCE              2 
#define KEY_STATE_REPEAT_START_DELAY    3 
#define KEY_STATE_REPEAT_DELAY          4 
 
#define NO_RELEASE_AFTER_STILL          ON 
 
 
 
/* ------------------------------------ 
    Macro Definitions 
   ------------------------------------ */ 
 
 
 
/* ------------------------------------ 
    Type Definitions 
   ------------------------------------ */ 
 
 
/* ------------------------------------ 
    Variables Definitions 
   ------------------------------------ */ 
static UB8 abKeyBfr[ KEY_BFR_SIZE ];       /* Keypad buffer */ 
 
/* Buffer index where next scan code will be inserted */ 
static UB8 bKeyBfrInIdx; 
 
/* Buffer index where next scan code will be removed */ 
static UB8 bKeyBfrOutIdx; 
 
 
#if (NO_RELEASE_AFTER_STILL) 
// To filter out the RELEASE key after STILL one. 
static BOOL fKeyNO_STILL; 
#endif 
 
 
/* ------------------------------------ 
    Function Prototypes 
   ------------------------------------ */ 
 
/* ------------------------------------------------------------------- 
    Name: KEY_BufferFlush - 
    Purpose: To flush the key buffer data structure. 
    Passed: None. 
    Returns: None. 
    Notes: 
   ------------------------------------------------------------------- */ 
void KEY_BufferFlush (void) 
{ 
    bKeyCnt         = 0; 
    bKeyBfrInIdx    = 0; 
    bKeyBfrOutIdx   = 0; 
} /* KEY_BufferFlush */ 
 
 
/* ------------------------------------------------------------------- 
    Name: KEY_BufferIn - 
    Purpose: To insert a scan code into the key buffer data structure. 
    Passed: 
        UB8 bCode = a scan code. 
    Returns: None. 
    Notes: 
        1) THIS ONE MIGHT BE CALLED FROM different ISRs / Code. 
           Therefore no local variables are allowed otherwise it causes 
           a overlay error in Keil-C. 
   ------------------------------------------------------------------- */ 
void KEY_BufferIn (UB8 bCode) 
{ 
    if (bCode) 
    { 
        if (bKeyCnt < KEY_BFR_SIZE) 
        { 
            bKeyCnt++; 
 
            abKeyBfr[ bKeyBfrInIdx++ ] = bCode; 
 
            if (bKeyBfrInIdx >= KEY_BFR_SIZE) 
                bKeyBfrInIdx = 0; 
        } /* if */ 
    } 
} /* KEY_BufferIn */ 
 
 
/* ------------------------------------------------------------------- 
    Name: KEY_BufferOut - 
    Purpose: To retrieve a scan code from the key buffer data structure. 
    Passed: None. 
    Returns: 
        KEY_NULL if there is no key in the key buffer. 
    Notes: 
   ------------------------------------------------------------------- */ 
UB8 KEY_BufferOut (void) 
{ 
    UB8 bCode; 
 
 
    if (bKeyCnt) 
    { 
        bKeyCnt--; 
 
        bCode = abKeyBfr[ bKeyBfrOutIdx ]; 
 
        bKeyBfrOutIdx++; 
        if (bKeyBfrOutIdx >= KEY_BFR_SIZE) 
            bKeyBfrOutIdx = 0; 
 
        return( bCode ); 
    } 
    else 
    { 
        return( KEY_NULL ); 
    } /* if */ 
} /* KEY_BufferOut */ 
 
 
/* ------------------------------------------------------------------- 
    Name: KEY_Decode - 
    Purpose: To decode keypad pins to scan code. 
    Passed: None. 
    Returns: 
        KEY_NULL if there is no key in the key buffer. 
 
    Notes: Keypad is active low. 
   ------------------------------------------------------------------- */ 
UB8 KEY_Decode (void) 
{ 
    return( (~KEY_IOPORT) & KEY_MASK ); 
} /* KEY_Decode */ 
 
 
/* ------------------------------------------------------------------- 
    Name: KEY_Hit - 
    Purpose: To check whether the key buffer is not empty. 
    Passed: None. 
    Returns: 
        TRUE if the key buffer is not empty. 
    Notes: 
   ------------------------------------------------------------------- */ 
BOOL KEY_Hit (void) 
{ 
    return( bKeyCnt > 0 ); 
} /* KEY_Hit */ 
 
 
/* ------------------------------------------------------------------- 
    Name: KEY_Init - 
    Purpose: To initialize the KEY module. 
    Passed: None. 
    Returns: None. 
    Notes: 
        KEY_Init() must be called before calling any other of 
    the user accessible functions. 
 
   ------------------------------------------------------------------- */ 
void KEY_Init (void) 
{ 
    // Setup KEYPAD input ! 
 
    #if (PLATFORM_CFG == PLATFORM_01_DMO1611A0) 
    // (01)VID540-100-027/BIT1611B0  (v1.00 2005/10/14 BIT1611B0 Demo Board) 
 
    KEY_iPOWER      = 1; 
 
    KEY_iMENU       = 1; 
    KEY_iSELECT     = 1; 
    KEY_iUP         = 1; 
    KEY_iDOWN       = 1; 
 
    #elif (PLATFORM_CFG == PLATFORM_04_DMO1611S0) 
    // (04)PLATFORM_04_DMO1611S0 (VID502-002-031,BIT1611BS0) 
 
    KEY_iPOWER      = 1; 
 
    KEY_iMENU       = 1; 
    KEY_iSELECT     = 1; 
    KEY_iUP         = 1; 
    KEY_iDOWN       = 1; 
 
    #elif (PLATFORM_CFG == PLATFORM_06_VTX0501) 
    // (06)PLATFORM_06_VTX0501 (BMW HS 2.1) 
 
    KEY_iPOWER      = 1; 
 
    KEY_iMENU       = 1; 
    KEY_iSELECT     = 1; 
    KEY_iUP         = 1; 
    KEY_iDOWN       = 1; 
 
    #else 
        #error KEY.C - Invalid PLATFORM_CFG ! 
 
    #endif /* PROJECT */ 
 
 
 
    #if (KEY_AUTO_REPEAT) 
    bTimerKeyAuto       = 0;    /* For key auto repeat feature */ 
    #endif // KEY_AUTO_REPEAT 
 
    #if (KEY_STILL_DETECTION) 
    // Pressed key duration ! 
    bKEY_STILL_INTERVAL = KEY_STILL_INTERVAL; 
    bTimerKeyPressed    = bKEY_STILL_INTERVAL; 
    #endif 
 
    KEY_BufferFlush(); 
 
    fKeyReleased    = TRUE; 
 
    bKeyScanState   = KEY_STATE_UP; 
 
    #if (KEY_VR_AIN21) 
    bKEY_VR_ADJUSTMENT  = KEY_VR_DEFAULT; 
    #endif 
 
} /* KEY_Init */ 
 
 
/* ------------------------------------------------------------------- 
    Name: KEY_Pressed - To check whether any keys are pressed. 
    Purpose: . 
    Passed: None. 
    Returns: 
        FALSE if no key pressed. 
     Notes: 
   ------------------------------------------------------------------- */ 
BOOL KEY_Pressed (void) 
{ 
    return( (KEY_IOPORT & KEY_MASK) != KEY_MASK ); 
} /* KEY_Pressed */ 
 
 
/* ------------------------------------------------------------------- 
    Name: KEY_Scan - 
    Purpose: To scan the keypad periodically. 
    Passed: None. 
    Returns: None. 
    Notes: 
        1) THIS ONE IS USUALLY CALLED FROM TIMER ISR ONLY 
        2) Local variables are allowed if it is NOT called by other ISRs 
           or code ! 
        3) The duration is at least 30ms between each call of this scan 
           function for avoiding de-bounce failure. 
 
   ------------------------------------------------------------------- */ 
void KEY_Scan (void) 
{ 
    #if (KEY_AUTO_REPEAT) 
    if (bTimerKeyAuto) 
        bTimerKeyAuto--; 
    #endif // KEY_AUTO_REPEAT 
 
    if (bTimerKeyPressed) 
        bTimerKeyPressed--; 
 
    #if (KEY_STILL_DETECTION) 
    if (bTimerKeyPressed == 1) 
    { 
        KEY_BufferFlush(); 
        KEY_BufferIn(bLastKey | KEY_MASK_STILL); 
 
        #if (NO_RELEASE_AFTER_STILL) 
        fKeyNO_STILL = FALSE; 
        #endif 
    } 
    #endif // KEY_STILL_DETECTION 
 
 
    switch (bKeyScanState) 
    { 
        case KEY_STATE_UP: 
            if (KEY_Pressed()) 
            { 
                bKeyScanState = KEY_STATE_DEBOUNCE; 
 
                #if (NO_RELEASE_AFTER_STILL) 
                fKeyNO_STILL = TRUE; 
                #endif 
            } 
            #if (KEY_STILL_DETECTION) 
            else 
            { 
                bTimerKeyPressed = 0; 
                fKeyReleased = TRUE; 
            } 
            #endif // KEY_STILL_DETECTION 
            break; 
 
 
        case KEY_STATE_DEBOUNCE: 
            if (KEY_Pressed()) 
            { 
                KEY_BufferIn(KEY_Decode()); 
 
                #if (KEY_AUTO_REPEAT) 
                bTimerKeyAuto = KEY_REPEAT_START_DELAY; 
                #endif // KEY_AUTO_REPEAT 
 
                bLastKey = KEY_Decode(); 
 
                #if (KEY_STILL_DETECTION) 
                if (bLastKey == KEY_POWER) 
                    bTimerKeyPressed = bKEY_STILL_INTERVAL; 
                #endif // KEY_STILL_DETECTION 
 
                bKeyScanState = KEY_STATE_REPEAT_START_DELAY; 
            } 
            else 
            { 
                bTimerKeyPressed = 0; 
                fKeyReleased = TRUE; 
 
                bKeyScanState = KEY_STATE_UP; 
            } 
            break; 
 
 
        case KEY_STATE_REPEAT_START_DELAY: 
            if (KEY_Pressed()) 
            { 
                #if (KEY_AUTO_REPEAT) 
                if (bTimerKeyAuto == 0) 
                { 
                    KEY_BufferIn(KEY_Decode()); 
 
                    bTimerKeyAuto = KEY_REPEAT_INTERVAL; 
 
                    bKeyScanState = KEY_STATE_REPEAT_DELAY; 
                } /* if */ 
                #endif // KEY_AUTO_REPEAT 
            } 
            else 
            { 
                #if (NO_RELEASE_AFTER_STILL) 
                if (fKeyNO_STILL) 
                #endif 
                { 
                    KEY_BufferFlush(); 
                    KEY_BufferIn(bLastKey | KEY_MASK_RELEASE); 
                } 
 
                bTimerKeyPressed = 0; 
                fKeyReleased = TRUE; 
 
                bKeyScanState = KEY_STATE_DEBOUNCE; 
            } /* if */ 
            break; 
 
 
        #if (KEY_AUTO_REPEAT) 
        case KEY_STATE_REPEAT_DELAY: 
            if (KEY_Pressed()) 
            { 
                if (bTimerKeyAuto == 0) 
                { 
                    KEY_BufferIn(KEY_Decode()); 
 
                    bTimerKeyAuto = KEY_REPEAT_INTERVAL; 
                } /* if */ 
            } 
            else 
            { 
                #if (NO_RELEASE_AFTER_STILL) 
                if (fKeyNO_STILL) 
                #endif 
                { 
                    KEY_BufferFlush(); 
                    KEY_BufferIn(bLastKey | KEY_MASK_RELEASE); 
                } 
 
                bTimerKeyPressed = 0; 
                fKeyReleased = TRUE; 
 
                bKeyScanState = KEY_STATE_DEBOUNCE; 
            } 
            break; 
        #endif // KEY_AUTO_REPEAT 
 
        default : 
            break; 
    } /* switch */ 
} /* KEY_Scan */ 
 
 
/* ------------------------------------------------------------------- 
    Name:  - 
    Purpose: . 
    Passed: None. 
    Returns: None. 
    Notes: 
   ------------------------------------------------------------------- */ 
 
/* ********************************************************************** 
 
    Description: 
 
 
   ********************************************************************** */ 
 
/* %% End Of File %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */