📄 keypad.c
字号:
/*
$Workfile: keypad.c $
$Revision: 1.49 $
$Date: Feb 09 2006 20:52:44 $
*/
#define __KEYPAD_C__
//******************************************************************************
//
// Copyright (C) 2002. GENESIS MICROCHIP INC. CONFIDENTIAL
// All rights reserved. No part of this program may be reproduced.
//
// Genesis Microchip Corp., 2150 Gold Street
// Alviso, CA 95002 USA
// Genesis Microchip Inc., 165 Commerce Valley Dr. West
// Thornhill, Ontario, Canada, L3T 7V8
//
//==============================================================================
//
// MODULE: keypad.c
//
// USAGE: Initialize and scan general purpose input-output keys.
//
//******************************************************************************
//******************************************************************************
// I N C L U D E F I L E S
//******************************************************************************
#include "inc\all.h"
#include "system\mcu186.h"
#include "math.h"
#if USE_KEYPAD_DRV_MODEL
#include <mem.h>
//******************************************************************************
// L O C A L D E F I N I T I O N S
//******************************************************************************
#define DEBUG_SCAN_CODE 0
#define DEBUG_KEYPAD 0
#if DEBUG_KEYPAD && DEBUG_MSG
#define msg(a,b) gm_Print((const char far *)a,b)
#else
#define msg(a,b)
#endif
#if defined(PHOENIX) || defined(TUCSON) || defined(PHOENIX_U)
WORD W_ArrayOfGPIOInputAddress[] = { GPINPUT1 /*, GPINPUT2, GPINPUT3*/ };
WORD W_ArrayOfGPIODirAddress[] = { GPIO_DIRCTRL1 /*, GPIO_DIRCTRL2, GPIO_DIRCTRL3 */};
#else
WORD W_ArrayOfGPIOInputAddress[] = { GPINPUT1, GPINPUT2, GPINPUT3 };
WORD W_ArrayOfGPIODirAddress[] = { GPIO_DIRCTRL1, GPIO_DIRCTRL2, GPIO_DIRCTRL3 };
#endif
typedef struct WBK_ST_KeyConvert
{
BYTE Key_Ph;
gmt_KEY_INDEX Key_Log;
}WBK_ST_KeyConvertType;
typedef struct WBK_ST_KeyTranslate
{
BYTE B_ArrayKeys[WB_NUMBER_OF_INPUT_SOURCE];
gmt_KEY_INDEX Key_Log;
}WBK_ST_KeyTranslateType;
//gmt_KEY_INDEX GlobalKeyArray[WB_NUMBER_OF_INPUT_SOURCE];
gmt_KEY_INDEX TranslateKey(BYTE B_PhVal, WBK_KEYPAD_DEFINITION ROM* Sp_KeyData);
#if ((IR_TYPE == IR_RECS80_EXT) || (IR_TYPE == IR_RECS80_EXT_INV))
BYTE B_IrCntBit;
WORD W_CntVal;
Ir_InitType IrInit;
WORD W_IrKey;
#endif
//******************************************************************************
// F U N C T I O N S
//******************************************************************************
//******************************************************************************
// S T A T I C F U N C T I O N P R O T O T Y P E S
//******************************************************************************
//******************************************************************************
// C O D E
//******************************************************************************
#if IR_TYPE == IR_RECS80_EXT_INV
//******************************************************************************
//
// FUNCTION: void far SetIrTimeout(void)
// USAGE: Set Ir timout for recieve inverse IR data
// INPUT: Status - TCLK timer status
// OUTPUT: none
// GLOBALS: none
// USED_REGS: none
//
//******************************************************************************
void far SetIrTimeoutInv(void)
{
gm_WriteRegWord(TCLK_TMR_COMP_B_0, gm_ReadRegWord(TCLK_TMR_VALUE_0) + IrInit.Settings.RECS80.Timeout);
gm_SetRegBitsByte(TCLK_TMR_CTRL_1 , COMP_CAPT_B_INT_EN);
}
//******************************************************************************
//
// FUNCTION: void far ExtRec80IrDriver(WORD Status)
// USAGE: External IR driver for recieve inverse IR data
// INPUT: Status - TCLK timer status
// OUTPUT: none
// GLOBALS: none
// USED_REGS: none
//
//******************************************************************************
void far ExtRecs80InvIrDriver(WORD Status)
{
static WORD W_PrevTime;
if(Status & COMP_CAPT_B_INT_ST) // inverse
{
// Timeout is expired.
W_IrKey = 0;
// disable timeout checking
gm_ClearRegBitsByte(TCLK_TMR_CTRL_1 , COMP_CAPT_B_INT_EN);
}
if(Status & COMP_CAPT_A_INT_ST) // inverse
{
// calculate time interval
WORD W_CaptureTime = gm_ReadRegWord(TCLK_TMR_COMP_A_0) - W_PrevTime; // inverse
W_PrevTime += W_CaptureTime;
if(!B_IrCntBit)
{
B_IrCntBit++;
}
else
{
if((W_CaptureTime > IrInit.Settings.RECS80.Header_Min) && (W_CaptureTime < IrInit.Settings.RECS80.Header_Max))
{
// Header is detected
B_IrCntBit = 2;
W_CntVal = 0;
SetIrTimeoutInv();
}
else if(B_IrCntBit > 1)
{
if(W_CaptureTime >= IrInit.Settings.RECS80.EdgeDelay)
{
B_IrCntBit++;
W_CntVal <<= 1;
if((W_CaptureTime < IrInit.Settings.RECS80.Logic1_Max) && (W_CaptureTime > IrInit.Settings.RECS80.Logic1_Min))
{
// logic "1" is detected
W_CntVal |= 1;
}
else if((W_CaptureTime > IrInit.Settings.RECS80.Logic0_Max) || (W_CaptureTime < IrInit.Settings.RECS80.Logic0_Min))
{
if((W_CaptureTime > IrInit.Settings.RECS80.Repeat_Max) && (IrInit.Type == IrType_NEC))
{
// repeat command is detected. Set new timeout
SetIrTimeoutInv();
}
B_IrCntBit = 0;
}
// enable timeout checking
if(IrInit.Type != IrType_NEC)
SetIrTimeoutInv();
}
}
}
if(B_IrCntBit == IrInit.Settings.RECS80.NumOfBits)
{
B_IrCntBit = 0;
W_IrKey = W_CntVal;
}
}
}
#endif
#if IR_TYPE == IR_RECS80_EXT
//******************************************************************************
//
// FUNCTION: void far SetIrTimeout(void)
// USAGE: Set Ir timout
// INPUT: Status - TCLK timer status
// OUTPUT: none
// GLOBALS: none
// USED_REGS: none
//
//******************************************************************************
void far SetIrTimeout(void)
{
gm_WriteRegWord(TCLK_TMR_COMP_A_0, gm_ReadRegWord(TCLK_TMR_VALUE_0) + IrInit.Settings.RECS80.Timeout);
gm_SetRegBitsByte(TCLK_TMR_CTRL_1 , COMP_CAPT_A_INT_EN);
}
//******************************************************************************
//
// FUNCTION: void far ExtRec80IrDriver(WORD Status)
// USAGE: External IR driver
// INPUT: Status - TCLK timer status
// OUTPUT: none
// GLOBALS: none
// USED_REGS: none
//
//******************************************************************************
void far ExtRec80IrDriver(WORD Status)
{
static WORD W_PrevTime;
if(Status & COMP_CAPT_A_INT_ST)
{
// Timeout is expired.
W_IrKey = 0;
// disable timeout checking
gm_ClearRegBitsByte(TCLK_TMR_CTRL_1 , COMP_CAPT_A_INT_EN);
}
if(Status & COMP_CAPT_B_INT_ST)
{
// calculate time interval
WORD W_CaptureTime = gm_ReadRegWord(TCLK_TMR_COMP_B_0) - W_PrevTime; // inverse
W_PrevTime += W_CaptureTime;
if(!B_IrCntBit)
{
B_IrCntBit++;
}
else
{
if((W_CaptureTime > IrInit.Settings.RECS80.Header_Min) && (W_CaptureTime < IrInit.Settings.RECS80.Header_Max))
{
// Header is detected
B_IrCntBit = 2;
W_CntVal = 0;
SetIrTimeout();
}
else if(B_IrCntBit > 1)
{
if(W_CaptureTime >= IrInit.Settings.RECS80.EdgeDelay)
{
B_IrCntBit++;
W_CntVal <<= 1;
if((W_CaptureTime < IrInit.Settings.RECS80.Logic1_Max) && (W_CaptureTime > IrInit.Settings.RECS80.Logic1_Min))
{
// logic "1" is detected
W_CntVal |= 1;
}
else if((W_CaptureTime > IrInit.Settings.RECS80.Logic0_Max) || (W_CaptureTime < IrInit.Settings.RECS80.Logic0_Min))
{
if((W_CaptureTime > IrInit.Settings.RECS80.Repeat_Max) && (IrInit.Type == IrType_NEC))
{
// repeat command is detected. Set new timeout
SetIrTimeout();
}
B_IrCntBit = 0;
}
// enable timeout checking
if(IrInit.Type != IrType_NEC)
SetIrTimeout();
}
}
}
if(B_IrCntBit == IrInit.Settings.RECS80.NumOfBits)
{
B_IrCntBit = 0;
W_IrKey = W_CntVal;
}
}
}
#endif
#ifdef WBK_FUNCTION_INITIRDRIVER_USED
//******************************************************************************
//
// FUNCTION: BYTE far InitIRDriver(BYTE ROM* Bp_Data)
// USAGE: First configure IR keypad driver
// INPUT: Bp_Data - pointer to keypad structure
// OUTPUT: none
// GLOBALS: none
// USED_REGS: none
//
//******************************************************************************
#pragma argsused
BYTE far InitIRDriver(BYTE ROM* Bp_Data)
{
#if IR_TYPE == IR_RC5
Ir_InitType IrCfg;
IrCfg.Type = IrType_RC5;
IrCfg.Settings.RC5.NumOfBits = 27;
IrCfg.Settings.RC5.FirstBitDelay = 5900;
IrCfg.Settings.RC5.Timeout = 200; // PDR # 11384 Old timeout = 300
gm_IrDriverInit(&IrCfg);
gm_WriteRegByte(TCLK_TMR_CTRL_0, (TCLK_TMR_EN | 0x80 | 0x10));
gm_WriteRegByte(TCLK_TMR_INT_STATUS, gm_ReadRegByte(TCLK_TMR_INT_STATUS));
gm_WriteRegByte(TCLK_TMR_CTRL_1, COMP_CAPT_B_INT_EN);
gm_WriteRegWord(TCLK_TMR_COMP_A_0, 11800);
#endif // IR_TYPE == IR_RC5
#if IR_TYPE == IR_RECS80
Ir_InitType IrCfg;
IrCfg.Type = IrType_RECS80;
IrCfg.Settings.RECS80.EdgeDelay = 200;
IrCfg.Settings.RECS80.Header_Max = 8000;
IrCfg.Settings.RECS80.Header_Min = 4296;
IrCfg.Settings.RECS80.Logic0_Max = 2237;
IrCfg.Settings.RECS80.Logic0_Min = 1700;
IrCfg.Settings.RECS80.Logic1_Max = 3938;
IrCfg.Settings.RECS80.Logic1_Min = 3222;
IrCfg.Settings.RECS80.NumOfBits = 16;
IrCfg.Settings.RECS80.Repeat_Max = 0;
IrCfg.Settings.RECS80.Timeout = 0xd1bc;
gm_IrDriverInit(&IrCfg);
gm_WriteRegByte(TCLK_TMR_CTRL_0, 0x85); // CAPTURE B, COMPARE A, TCLK/16, EN
gm_WriteRegByte(TCLK_TMR_INT_STATUS, gm_ReadRegByte(TCLK_TMR_INT_STATUS));
gm_WriteRegByte(TCLK_TMR_CTRL_1, COMP_CAPT_B_INT_EN);
#endif // IR_TYPE == IR_RECS80
#if IR_TYPE == IR_NEC
Ir_InitType IrCfg;
IrCfg.Type = IrType_NEC;
IrCfg.Settings.RECS80.EdgeDelay = 200;
IrCfg.Settings.RECS80.Header_Max = 8000;
IrCfg.Settings.RECS80.Header_Min = 5817;
IrCfg.Settings.RECS80.Logic0_Max = 582;
IrCfg.Settings.RECS80.Logic0_Min = 402;
IrCfg.Settings.RECS80.Logic1_Max = 1074;
IrCfg.Settings.RECS80.Logic1_Min = 895;
IrCfg.Settings.RECS80.NumOfBits = 36;
IrCfg.Settings.RECS80.Repeat_Max = 4922;
IrCfg.Settings.RECS80.Timeout = 0xC042;
gm_IrDriverInit(&IrCfg);
gm_WriteRegByte(TCLK_TMR_CTRL_0, 0x87); // CAPTURE B, COMPARE A, TCLK/32, EN
gm_WriteRegByte(TCLK_TMR_INT_STATUS, gm_ReadRegByte(TCLK_TMR_INT_STATUS));
gm_WriteRegByte(TCLK_TMR_CTRL_1, COMP_CAPT_B_INT_EN);
#endif // IR_TYPE == IR_NEC
#if IR_TYPE == IR_RECS80_EXT
IrInit.Type = IrType_RECS80;
IrInit.Settings.RECS80.EdgeDelay = 200;
IrInit.Settings.RECS80.Header_Max = 10000;
IrInit.Settings.RECS80.Header_Min = 4296;
IrInit.Settings.RECS80.Logic0_Max = 2237;
IrInit.Settings.RECS80.Logic0_Min = 1700;
IrInit.Settings.RECS80.Logic1_Max = 3938;
IrInit.Settings.RECS80.Logic1_Min = 3222;
IrInit.Settings.RECS80.NumOfBits = 16;
IrInit.Settings.RECS80.Repeat_Max = 0;
IrInit.Settings.RECS80.Timeout = 0xd1bc;
B_IrCntBit = W_IrKey = 0;
{
Ir_InitType IrCfg;
IrCfg.Type = IrType_EXT;
IrCfg.Settings.EXTDRV.ExtDriver = (ExternalIrDriverType)ExtRec80IrDriver;
gm_IrDriverInit(&IrCfg);
}
gm_WriteRegByte(TCLK_TMR_CTRL_0, 0x85); // Module A in capture mode, Module B in compare mode, Div = 16
gm_WriteRegByte(TCLK_TMR_INT_STATUS, gm_ReadRegByte(TCLK_TMR_INT_STATUS));
gm_WriteRegByte(TCLK_TMR_CTRL_1, COMP_CAPT_B_INT_EN); // enable module B interrupt
#endif // IR_TYPE == IR_RECS80_EXT
#if IR_TYPE == IR_RECS80_EXT_INV
IrInit.Type = IrType_RECS80;
IrInit.Settings.RECS80.EdgeDelay = 200;
IrInit.Settings.RECS80.Header_Max = 10000;
IrInit.Settings.RECS80.Header_Min = 4296;
IrInit.Settings.RECS80.Logic0_Max = 2237;
IrInit.Settings.RECS80.Logic0_Min = 1700;
IrInit.Settings.RECS80.Logic1_Max = 3938;
IrInit.Settings.RECS80.Logic1_Min = 3222;
IrInit.Settings.RECS80.NumOfBits = 16;
IrInit.Settings.RECS80.Repeat_Max = 0;
IrInit.Settings.RECS80.Timeout = 0xd1bc;
B_IrCntBit = W_IrKey = 0;
{
Ir_InitType IrCfg;
IrCfg.Type = IrType_EXT;
IrCfg.Settings.EXTDRV.ExtDriver = (ExternalIrDriverType)ExtRecs80InvIrDriver;
gm_IrDriverInit(&IrCfg);
}
gm_WriteRegByte(TCLK_TMR_CTRL_0, 0x25); // Module B in capture mode, Module A in compare mode, Div = 16
gm_WriteRegByte(TCLK_TMR_INT_STATUS, gm_ReadRegByte(TCLK_TMR_INT_STATUS));
gm_WriteRegByte(TCLK_TMR_CTRL_1, COMP_CAPT_A_INT_EN); // Enable module A interrupt
#endif // IR_TYPE == IR_RECS80_EXT_INV
gm_ClearRegBitsByte(GPIO_DIRCTRL3, BIT5);
gm_SetRegBitsByte(MISC_OCMMASK, BIT5);
WRITE_PCB_REG(I0CON, 0x00);
CLEAR_PCB_REG_BITS(IMASK, I0);
return 0;
}
#endif // WBK_FUNCTION_INITIRDRIVER_USED
WORD prevkey = 0;
#ifdef WBK_FUNCTION_GETIRVALUE_USED
BYTE far GetIRValue(BYTE ROM* Bp_Data)
{
gmt_KEY_INDEX KeyIndex;
WORD W_CntIrKey;
#if IR_TYPE == IR_RC5
W_CntIrKey = gm_GetIrKey();
if(W_CntIrKey && !(W_CntIrKey & 0x3f))
W_CntIrKey = 128;
else
W_CntIrKey &= 0x3f;
#endif // IR_TYPE == IR_RC5
#if IR_TYPE == IR_RECS80
W_CntIrKey = gm_GetIrKey() & 0x3f;
#endif // IR_TYPE == IR_RECS80
#if IR_TYPE == IR_NEC
W_CntIrKey = gm_GetIrKey() & 0xff;
#endif
#if ((IR_TYPE == IR_RECS80_EXT) || (IR_TYPE == IR_RECS80_EXT_INV))
W_CntIrKey = W_IrKey & 0x3f;
#endif // ((IR_TYPE == IR_RECS80_EXT) || (IR_TYPE == IR_RECS80_EXT_INV))
KeyIndex = TranslateKey(W_CntIrKey, (WBK_KEYPAD_DEFINITION ROM*)Bp_Data);
return KeyIndex;
}
#endif // WBK_FUNCTION_GETIRVALUE_USED
#ifdef WBK_FUNCTION_GETGPIOVALUE_USED
//******************************************************************************
//
// FUNCTION: void GetMaskGPIO (WBK_KEYPAD_DEFINITION ROM* Bp_Data)
// USAGE: This function calculates mask for current GPIO
// INPUT: Bp_Data - pointer to keypad structure
// OUTPUT: BYTE - mask
// GLOBALS: none
// USED_REGS: none
//
//******************************************************************************
BYTE GetMaskGPIO(WBK_KEYPAD_DEFINITION ROM* Bp_Data)
{
BYTE B_Count = ((WBK_KEYPAD_DEFINITION ROM*)Bp_Data)->B_KeysNumber;
BYTE B_KeysMask = 0;
WBK_ST_KeyConvertType ROM* Sp_Masks = (WBK_ST_KeyConvertType ROM*)(((WBK_KEYPAD_DEFINITION ROM*)Bp_Data)->Bp_KeyValues);
for (; B_Count; B_Count--)
{
B_KeysMask |= Sp_Masks->Key_Ph;
Sp_Masks++;
}
return B_KeysMask;
}
//******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -