📄 mskeypad.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 + -