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

📄 mskeypad.c

📁 mstar 776 开发的车载dvd
💻 C
字号:
///////////////////////////////////////////////////////////////////////////////
///@file msKeypad.c
///@brief Keypad Module
///@author MStarSemi Inc.
///////////////////////////////////////////////////////////////////////////////

#include "board.h"

#define _MSKEYPAD_C_
#include "hwreg.h"
#include "mreg51.h"
#include "msIR.h"
#include "msKeypad.h"
#include "msAPI_Timer.h"
#if( POWER_KEY_PAD_BY_INTERRUPT )
#include "sramvar.h"
#endif

#include "drvGlobal.h"// kevin e
#include "drvSAR.h"

#define CheckWakeupKeyPad(x) ((x == IRKEY_POWER) ||             \
                              (x == IRKEY_CHANNEL_MINUS) ||     \
                              (x == IRKEY_CHANNEL_PULS) ||      \
                              (x == IRKEY_INPUT_SOURCE))


//#define KeypadUnPressedTimerCount 7
//static U8 KeyPadCheckCount, PreviousCMD, PressKey;

#if KEYPAD_USE_ISR
//static U32 KeypadSuccessTime; //100 ms based
//BOOLEAN KeypadRepeatStart;
static U8 PreviousCMD;
#else
static U8 KeyPadCheckCount, PreviousCMD, PressKey;
static U32 KeyPadTimePeriod;
extern U32 volatile g100msTimeCount;
#endif

extern U32 volatile g100msTimeCount;

unsigned char tADCKeyLevel[] =
{
    ADC_KEY_L0,
    ADC_KEY_L1,
    ADC_KEY_L2,
    ADC_KEY_L3,
};

unsigned char tADC1KeyLevel[] =
{
    ADC1_KEY_L0,
    ADC1_KEY_L1,
    ADC1_KEY_L2,
    ADC1_KEY_L3,
    ADC1_KEY_L4,
    ADC1_KEY_L5,
    ADC1_KEY_L6,
    ADC1_KEY_L7,
};

unsigned char code tADCKey1Flag[] =
{
    ADC_KEY_1_L0_FLAG,
    ADC_KEY_1_L1_FLAG,
    ADC_KEY_1_L2_FLAG,
    ADC_KEY_1_L3_FLAG,
};

unsigned char code tADCKey2Flag[] =
{
    ADC_KEY_2_L0_FLAG,
    ADC_KEY_2_L1_FLAG,
    ADC_KEY_2_L2_FLAG,
    ADC_KEY_2_L3_FLAG,
    ADC_KEY_2_L4_FLAG,
    ADC_KEY_2_L5_FLAG,
    ADC_KEY_2_L6_FLAG,
    ADC_KEY_2_L7_FLAG,
};

void msKeypad_Init(void)
{
    #if KEYPAD_USE_ISR
    int i=0;
    PreviousCMD = 0;
    //KeyPadCheckCount = 0;
    //PressKey = FALSE;
    for(i=0;i<sizeof(KEYPAD_LV_CHANNEL);i++){
        KEYPAD_LV_CHANNEL[i]=0;
    }

    for(i=0;i<sizeof(KEYPAD_PREVIOUS_LV_CHANNEL);i++){
        KEYPAD_PREVIOUS_LV_CHANNEL[i]=0;
    }

     for(i=0;i<sizeof(KEYPAD_LV_COUNT_CHANNEL);i++){
        KEYPAD_LV_COUNT_CHANNEL[i]=0;
    }
    #else
    PreviousCMD = 0;
    KeyPadCheckCount = 0;
    PressKey = FALSE;
    #endif
/*//--------------------------------------
// MOSES    // kevin e

    //SAR clock Divder
    XBYTE[0x3A13] = 0xF1;
    XBYTE[0x3A12] = 0x00;

    //test select, not used.
    XBYTE[0x3A11] = 0xF2;
    XBYTE[0x3A10] = 0x00;

    //SAR config. start/reset.
	XBYTE[REG_SAR_CTRL0] = 0xA0;
 	XBYTE[REG_SAR_CTRL1] = 0x02;

	XBYTE[REG_SAR_CTRL2] = 0x05;
	XBYTE[REG_SAR_CTRL3] = 0x00;

    //Select PIN_SAR as SAR input, Enable SAR Function
	XBYTE[REG_SAR_CTRL20] = 0xFF;
	XBYTE[REG_SAR_CTRL21] = 0x80;

    //change PIN_SAR3 as SAR3 input
    XBYTE[0x1EAF] = 0x01;
//--------------------------------------*/

#if( POWER_KEY_PAD_BY_INTERRUPT )
    u8PwrKeypadIntFlag = FALSE;
#endif

    printf("\r\n *** Init Key done ***");   // kevin test
}

/******************************************************************************/
///Keypad get ADC Channel value
///@param pkey \b IN ADC Channel
///@param pflag \b IN Pointer to the ADC Channel value
/******************************************************************************/
/*U8 msKeypad_Get_ADC_Channel(U8 Channel, U8 *pvalue)
{
    U8 u8Status = 0;
    switch(Channel)
    {
        case KEYPAD_ADC_CHANNEL_1:
            *pvalue = XBYTE[REG_SAR_ADCOUT1] & MASK_SAR_ADCOUT;
            break;
        case KEYPAD_ADC_CHANNEL_2:
            *pvalue = XBYTE[REG_SAR_ADCOUT2] & MASK_SAR_ADCOUT;
            break;
        case KEYPAD_ADC_CHANNEL_3:
            *pvalue = XBYTE[REG_SAR_ADCOUT3] & MASK_SAR_ADCOUT;
            break;
        case KEYPAD_ADC_CHANNEL_4:
            *pvalue = XBYTE[REG_SAR_ADCOUT4] & MASK_SAR_ADCOUT;
             break;
        default:
            u8Status = 1;
            *pvalue = 0xFF;
            break;
    }
    return u8Status;
}*/

#if KEYPAD_USE_ISR
//this function will not check if key is pressed
static BOOLEAN msKeypad_IsKeyRepeat(U8 channelIdx)
{
    return (KEYPAD_LV_COUNT_CHANNEL[channelIdx]>KEYPAD_LV_STABLE_COUNT);
}

//modified by using ISR
BOOLEAN msKeypad_CH_GetKey(U8 *pkey, U8* pflag)
{
    U8  *Keymapping;
    U8 Channel;
    *pkey = 0xFF;
    *pflag = 0;



    //check if key pressed
    for (Channel=0; Channel<ADC_KEY_CHANNEL_NUM; Channel++)
    {
         if(KEYPAD_LV_CHANNEL[Channel]>0){
             break;
         }
    }


    if(Channel<ADC_KEY_CHANNEL_NUM)//Key pressed
    {
        //decide key map
        switch(Channel)
        {
            case KEYPAD_ADC_CHANNEL_1:
                Keymapping = &tADCKey1Flag;
                break;
            case KEYPAD_ADC_CHANNEL_2:
                Keymapping = &tADCKey2Flag;
                break;
            default:
                break;
        }

        //process key
        *pkey = *(Keymapping+(KEYPAD_LV_CHANNEL[Channel]-1));
        *pflag=msKeypad_IsKeyRepeat(Channel);
        KEYPAD_LV_CHANNEL[Channel]=0;//reset the buffer

        /*
        if(*pflag&&(g100msTimeCount-KeypadSuccessTime)<=KeypadRepeatTimerCount)
        {
            return FALSE;
        }

        KeypadSuccessTime=g100msTimeCount;
        */

        return TRUE;

    }
    else
    {
        return FALSE;
    }

}
#else


BOOLEAN msKeypad_CH_GetKey(U8 Channel, U8 *pkey, U8* pflag)
{
    U8 i, j, KEY_LV[ADC1_KEY_LEVEL], *Keymapping, LV_NUM;
    U16 Key_Value;

    *pkey = 0xFF;
    *pflag = 0;

#if( POWER_KEY_PAD_BY_INTERRUPT )
    if (u8PwrKeypadIntFlag)
    {
        u8PwrKeypadIntFlag = FALSE;
        *pkey = IRKEY_POWER;
        return TRUE;
    }
#endif

    switch(Channel)
    {
        case KEYPAD_ADC_CHANNEL_1:
            Keymapping = &tADCKey1Flag;
            LV_NUM = ADC_KEY_LEVEL;

            for(i=0; i<ADC_KEY_LEVEL; i++)
                KEY_LV[i] = 0;
            break;

        case KEYPAD_ADC_CHANNEL_2:
            Keymapping = &tADCKey2Flag;
            LV_NUM = ADC1_KEY_LEVEL;

            for(i=0; i<ADC1_KEY_LEVEL; i++)
                KEY_LV[i] = 0;
            break;
        default:
            break;
    }

    for(i=0;i<KEYPAD_STABLE_NUM;i++)
    {
        if (drvSAR_Get_ADC_Channel(Channel, &Key_Value) == 0)
        {
            #if (SAR_REOLUTION_SEL == RESOLUTION_IT_10BIT)
            Key_Value /= 4;
            #endif

            if (Channel == KEYPAD_ADC_CHANNEL_1)
            {
                for (j=0;j<ADC_KEY_LEVEL;j++)
                {
                    if(Key_Value < tADCKeyLevel[j])
                    {
                        KEY_LV[j]++;
                        //printf("\r\nKey_Value=%bx", Key_Value);// kevin test
                        break;
                    }
                }
            }
            else if (Channel == KEYPAD_ADC_CHANNEL_2)
            {
                for (j=0;j<ADC1_KEY_LEVEL;j++)
                {
                    if(Key_Value < tADC1KeyLevel[j])
                    {
                        KEY_LV[j]++;
                        //printf("\r\nKey1_Value=%bx", Key_Value);// kevin test
                        break;
                    }
                }
            }
        }
    }

    for(i=0; i<LV_NUM; i++)
    {
        //printf("\r\nKEY_LV[%bu]=%bu", i, KEY_LV[i]);
        //printf("\r\nKeyPadCheckCount=%bu", KeyPadCheckCount);

        if(KEY_LV[i] > KEYPAD_STABLE_NUM_MIN)
        {
            PressKey = TRUE;
            *pkey = *(Keymapping+i);
            if (PreviousCMD != *pkey)
            {
                PreviousCMD = *pkey;
                KeyPadCheckCount = 0;
                //puts("\r\nDiff pkey");
            }
            else
            {
                if (KeyPadCheckCount < KEYPAD_KEY_VALIDATION)
                {
                    KeyPadCheckCount++;
                    //puts("\r\nKEYPAD_KEY_IVALIDATION");// kevin test
                    return FALSE;
                }
                else if (KeyPadCheckCount == KEYPAD_KEY_VALIDATION)
                {
                    KeyPadCheckCount++;
                    KeyPadTimePeriod = g100msTimeCount;
                    //puts("\r\nKEYPAD_KEY_VALIDATION");// kevin test
                    return TRUE;
                }

                if (KeyPadCheckCount == KEYPAD_REPEAT_KEY_CHECK)	//3+2
                {
                    if (g100msTimeCount > KeyPadTimePeriod + KEYPAD_REPEAT_PERIOD/3)
                    {
                        KeyPadTimePeriod = g100msTimeCount;
                        KeyPadCheckCount = KEYPAD_REPEAT_KEY_CHECK_1;
                        *pflag = 0x01;
                    }
                    else
                    {
                    	*pkey = 0xFF;
                    	*pflag = 0x01;
                    }
                    //puts("\r\nKEYPAD_KEY_VALIDATION Repeat");// kevin test

                        return TRUE;
                }
                else if (KeyPadCheckCount == KEYPAD_REPEAT_KEY_CHECK_1)	//3+3
                {
                    if (g100msTimeCount > KeyPadTimePeriod)
                    {
                        KeyPadTimePeriod = g100msTimeCount;
                        KeyPadCheckCount = KEYPAD_REPEAT_KEY_CHECK_1;
                        *pflag = 0x01;
                    }
                    else
                    {
                    	*pkey = 0xFF;
                    	*pflag = 0x01;
                    }
                    //puts("\r\nKEYPAD_KEY_VALIDATION Repeat1");// kevin test

                        return TRUE;
                 }

                if (g100msTimeCount > KeyPadTimePeriod + KEYPAD_REPEAT_PERIOD)	//if 700ms
                {
                    KeyPadTimePeriod = g100msTimeCount;
                    KeyPadCheckCount = KEYPAD_REPEAT_KEY_CHECK;	//3+2
                    *pflag = 0x01;
                    //puts("\r\nKEYPAD_KEY_VALIDATION Repeat2");// kevin test
                    return TRUE;
                }
                else
                {
                    //puts("\r\nKEYPAD_KEY_VALIDATION Repeat2");// kevin test
                    return FALSE;
                }
            }
        }
    }

    if(Channel == ADC_KEY_LAST_CHANNEL)
    {
        if (PressKey)
            PressKey = FALSE;
        else
            PreviousCMD = 0xFF;
    }

    return FALSE;
}
#endif

/******************************************************************************/
///Keypad get key value and repeat flag
///@param pkey \b IN return the key value(The same as Irda key value)
///@param pflag \b IN return the repeat flag(1:Repeat)
/******************************************************************************/
BOOLEAN msKeypad_GetKey(U8 *pkey, U8 *pflag)
{
    #if KEYPAD_USE_ISR

    // check PAD_WAKEUP / PAD_INT status
    if (!(XBYTE[PM_PD] & (POWER_KEY_SEL == POWER_KEY_PAD_INT ? 0x20 : 0x10)))
    {
        *pkey = IRKEY_POWER;
        *pflag = 0;
        return TRUE;
    }

    return msKeypad_CH_GetKey(pkey, pflag);

    #else

    U8 Channel;

    // check PAD_WAKEUP / PAD_INT status
    /*if (!(XBYTE[PM_PD] & (POWER_KEY_SEL == POWER_KEY_PAD_INT ? 0x20 : 0x10)))
    {
        *pkey = IRKEY_POWER;
        *pflag = 0;
        return TRUE;
    }*/

    for (Channel=0; Channel<2; Channel++)
    {
        if (msKeypad_CH_GetKey(Channel, pkey, pflag))
        {
            return TRUE;
        }
    }
    return FALSE;

    #endif

}
extern U8 data KeypadCount, KeypadSamplePeriod;
BOOLEAN MDrv_Power_CheckPowerOnKeyPad(void)
{
    U8 data KeypadCHValue;

#if( POWER_KEY_PAD_BY_INTERRUPT )
    if(u8PwrKeypadIntFlag){
        u8PwrKeypadIntFlag = FALSE;
        return TRUE;
    }
#endif

    KeypadSamplePeriod++;

    //lachesis 2007-01-03 9:53坷傈
    if(KeypadSamplePeriod > 20)
    {
    	KeypadSamplePeriod = 0;
        KeypadCount = 0;
    }

    KeypadCHValue = XBYTE[REG_SAR_ADCOUT1];

    if(CheckWakeupKeyPad(ADC_KEY_1_L0_FLAG))
    {
        if (KeypadCHValue <= ADC_KEY_L0)
            KeypadCount++;
    }
    if(CheckWakeupKeyPad(ADC_KEY_1_L1_FLAG))
    {
        if ((KeypadCHValue > ADC_KEY_L0) &&
            (KeypadCHValue <= ADC_KEY_L1))
            KeypadCount++;
    }
    if(CheckWakeupKeyPad(ADC_KEY_1_L2_FLAG))
    {
        if ((KeypadCHValue > ADC_KEY_L1) &&
            (KeypadCHValue <= ADC_KEY_L2))
            KeypadCount++;
    }
    if(CheckWakeupKeyPad(ADC_KEY_1_L3_FLAG))
    {
        if ((KeypadCHValue > ADC_KEY_L2) &&
            (KeypadCHValue <= ADC_KEY_L3))
            KeypadCount++;
    }

    KeypadCHValue = XBYTE[REG_SAR_ADCOUT2];

    if(CheckWakeupKeyPad(ADC_KEY_2_L0_FLAG))
    {
        if (KeypadCHValue <= ADC_KEY_L0)
            KeypadCount++;
    }
    if(CheckWakeupKeyPad(ADC_KEY_2_L1_FLAG))
    {
        if ((KeypadCHValue > ADC_KEY_L0) &&
            (KeypadCHValue <= ADC_KEY_L1))
            KeypadCount++;
    }
    if(CheckWakeupKeyPad(ADC_KEY_2_L2_FLAG))
    {
        if ((KeypadCHValue > ADC_KEY_L1) &&
            (KeypadCHValue <= ADC_KEY_L2))
            KeypadCount++;
    }
    if(CheckWakeupKeyPad(ADC_KEY_2_L3_FLAG))
    {
        if ((KeypadCHValue > ADC_KEY_L2) &&
            (KeypadCHValue <= ADC_KEY_L3))
            KeypadCount++;
    }

    if(KeypadCount > 10)
        return TRUE;
    else
        return FALSE;
}

void msKeypad_ClearBuffer()
{
    U8 i;
    for(i=0;i<sizeof(KEYPAD_LV_CHANNEL);i++)
    {
        KEYPAD_LV_CHANNEL[i]=0;
    }
}
#undef _MSKEYPAD_C_

⌨️ 快捷键说明

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