📄 pmp_key_task.c
字号:
static UINT16 LastKey;
// key TASK 的序列
static UINT32 keyDrvQueBuf[KEY_DRV_QUE_SIZE];
// 定时器进行按键的处理
static void process_powersave_period( void );
// 按键对节电模式的处理
static void process_powersave_key( void );
static UINT32 SPMP_KeyScan_Enable_Flag=1;
extern UINT32 g_uiStartFlag; //add for nes game
/*
* 物理按键 和 GUI 消息的对应表 (用户可以修改)
*/
static const UINT8 key_map_table[13][2] =
{
// 物理扫描值 GUI 按键值
{KEY_UP, GUI_KEY_UP},
{KEY_DOWN, GUI_KEY_DOWN},
{KEY_LEFT, GUI_KEY_LEFT},
{KEY_RIGHT, GUI_KEY_RIGHT},
{KEY_OK, GUI_KEY_OK},
{KEY_ESC, GUI_KEY_ESC},
{KEY_A, GUI_KEY_F1},
{KEY_B, GUI_KEY_F2},
// 【10/25/2006】 17:27 lanzhu 根据 5K 键盘对应关系进行整理
{KEY_TELE, GUI_KEY_MENU},
{KEY_WIDE, GUI_KEY_TAB},
{KEY_M, GUI_KEY_F3},
{KEY_RESET, GUI_KEY_F4},
{KEY_START, GUI_KEY_START},
};
/*
* 按键与按键音转换表 (用户可以修改)
*/
static const UINT8 key_tone_table[8][2] =
{
// 物理键值 在配置表中的偏移
{KEY_UP, 0},
{KEY_DOWN, 1},
{KEY_LEFT, 2},
{KEY_RIGHT, 3},
{KEY_ESC, 4},
{KEY_OK, 5},
{KEY_WIDE, 6},
{KEY_TELE, 7},
};
/*
* 物理按键 和 NES GAME 内在键值的对应表格 (用户可以修改)
*/
#define KEY_POWER (0x1111)
#define PMP_NES_EXIT (0x1112)
#define NES_KEY_NUM (10)
static const UINT32 nes_game_key_table[10][2] =
{
// 物理键值 NES GAME 键值
{DUMMY_KEY, 0x00 }, // 按键的释放动作, 用户不能改动
{KEY_UP, MCATCH_EVENT_KEY_UP },
{KEY_DOWN, MCATCH_EVENT_KEY_DOWN },
{KEY_LEFT, MCATCH_EVENT_KEY_LEFT },
{KEY_RIGHT, MCATCH_EVENT_KEY_RIGHT },
{KEY_OK, MCATCH_EVENT_KEY_START },
{KEY_ESC, MCATCH_EVENT_KEY_SELECT },
{KEY_TELE, MCATCH_EVENT_KEY_A },
{KEY_WIDE, MCATCH_EVENT_KEY_B },
{KEY_POWER, PMP_NES_EXIT },
};
/**************************************************************************
* E X T E R N A L R E F E R E N C E S *
**************************************************************************/
extern void* aptask_q;
extern UINT32 SPMP_GetHoldKeyStatus(void);
/**************************************************************************
* F U N C T I O N D E C L A R A T I O N S *
**************************************************************************/
static void clr_PowerDown( void ); // set gPowerDown 0x00;
static UINT16 get_PowerDown( void ); // get gPowerDown
static void increase_PowerDown( void ); // gPowerDown ++
// 定时器对自动关机的处理
static void process_autooff_period( void );
// 按键对自动关机的处理
static void process_autooff_key( void );
// 检测 关机键是否被按下
static UINT16 power_off_detect( void );
// 初始化 功能端口
static void function_port_initial( void );
#ifndef EVB_SN_V10
static void key_port_initial( void );// 初始化 键盘端口的 硬件设置 ( S+MM开发板)
static UINT16 get_key_value( void ); // 获得键盘端口的值 (S+MM EVB )
#endif
// 初始化 键盘端口的 硬件设置 ( 北阳 开发板 V10 )
//static void key_port_initial_snv10( void );
// 北阳 SN-6047B 开发板的初始化程序
static void key_port_initial_sn6047b( void );
// 扫描端口的值( SN EVB V10)
static UINT16 get_key_value_snv10( void );
// 检查一个数据中 "0" 的个数
static UINT16 get_zero_bits( UINT32 data, UINT16 len );
// 输入一个数值和需要检查的位数, 返回第一个0的在该数值中的偏移值
static UINT16 get_zero_position( UINT32 data, UINT16 len );
// 将键盘扫描码 转换为 GUI 能够识别的键值编码
static UINT16 phy2gui_value( UINT16 physical_value);
// 启动键盘任务的程序
void SPMP_KeyDriverTimerFunc( void );
static void set_reg_bit(UINT32 RegAddr, UINT16 BitOffset, UINT16 Flag);
//获取键扫描开启/关闭状态
UINT32 SPMP_KeyScan_EnableStatusGet(void);
// 关掉系统电源
void SPMP_PowerControl ( UINT16 flag );
// 设定和获得 是否需要进行POWER 键的扫描
extern void SPMP_Set_ScanPowerKey( UINT16 value );
extern UINT16 SPMP_Get_ScanPowerKey( void );
// 判断是否需要进行GUI 消息的发送
static UINT16 judge_gui_msg( UINT16 msg );
// 内部函数 NES 键盘的处理
static UINT16 nes_key_process( UINT16 key_value );
// 内部函数 GUI 键盘的处理
static UINT16 gui_key_process( UINT16 LastKey, UINT16 PhyKeyValue );
// 获得 POWER 是否被按下的状况
static UINT16 get_power_key_status( void );
// 设置 POWER 是否被按下的状况
static void set_power_key_status( UINT16 data );
// 在 NES状态下对 POWER 键的处理
static void nes_power_process( UINT16 data );
// 将一个物理键值转换为NES 键值
static UINT32 phy_2_nes_key( UINT16 phy_key );
extern UINT32 SPMP_GetPwrStatus( void);
static void process_lowpower_period( void );
/************************************************************************/
/* 输入一个按键值, 得到按键音的位置索引值
input:
key_value [in] UINT16
output:
按键音的位置索引值
func:
*/
/************************************************************************/
UINT16 SPMP_KeyTone_GetIndex( UINT16 key_value )
{
UINT16 i;
for(i=0x00; i<0x08; i++)
{
if ( key_tone_table[i][0] == key_value )
{
return key_tone_table[i][1];
}
}
return (-1);
}
/************************************************************************/
/* 设定是否需要进行开关机键的扫描
input:
value 0 不需要扫描
非0值需要进行扫描
output:
void
*/
/************************************************************************/
void SPMP_Set_ScanPowerKey( UINT16 value )
{
gScanPowerKey = value;
return;
}
UINT16 SPMP_Get_ScanPowerKey( void )
{
return gScanPowerKey;
}
/************************************************************************/
/* 设定自动关机计数器的值
input:
value [in] UINT32
output:
void
func:
*/
/************************************************************************/
void SPMP_Set_AutoOffCnt(UINT32 value)
{
gBakAutoOffCount = value; // 备份值
gNowAutoOffCount = value; // 当前值
return;
}
/************************************************************************/
/* 键盘对节电的处理
input:
output:
func: 按键对节电模式的处理
note:
*/
/************************************************************************/
static void process_powersave_key( void )
{
// 如果是 不需要进行节电,直接返回
if ( DISABLE_POWER_SAVE == SPMP_Get_PowerSaveFlag() ) {
return;
}
// 如果当前计数值为0, 说明已经熄灭掉了
if( !SPMP_Get_PowerSaveCount() )
{
SPMP_LCM_LightCtrl( LCM_LIGHT_ENABLE ); // 点亮屏幕的背光
}
SPMP_Reset_PowerSaveCount(); // 将当前的节电值进行复位
return;
}
/************************************************************************/
/* 定时对自动关机进行检测
input:
output:
func:
note:
*/
/************************************************************************/
static void process_autooff_period( void )
{
// 如果是禁止自动关机, 返回不用处理
if( SPMP_AUTO_POWER_OFF_DISABLE == SPMP_Get_AutoPowerOff()){
return;
}
#ifdef KEY_DEBUG_1211
DEBUG_OUTPUT(("\r\ AutoOff = 0x%x\r\n", gNowAutoOffCount));
#endif
if ( gNowAutoOffCount ) {
gNowAutoOffCount --; // 计数值减一
}
else
{
increase_PowerDown(); // gPowerDown ++
#ifdef KEY_DEBUG_1211
DEBUG_OUTPUT(("\r\n自动关机, 发送消息!\r\n"));
#endif
SPMP_SendGUIMessage((UINT8)MSG_OTHER,(UINT32)POWER_DOWN_PREPARE, (UINT8)NULL);
}
return;
}
/*
* 按键对自动关机的处理, 每次收到自动关机后, 复位计数值
*/
static void process_autooff_key( void )
{
gNowAutoOffCount = gBakAutoOffCount; // 使用备份值
return;
}
/************************************************************************/
/* 定时对进行节电的处理
input:
output:
func:
*/
/************************************************************************/
static void process_powersave_period( void )
{
UINT16 i;
// 如果是 不需要进行节电,直接返回成功
if ( DISABLE_POWER_SAVE == SPMP_Get_PowerSaveFlag() ) {
return;
}
// 获取当前的计数值
i = SPMP_Get_PowerSaveCount();
if(!i){ // 如果已经是 0 了,直接返回, 不需要继续处理
return;
}
// 计数值减一
SPMP_Dec_PowerSaveCount();
if ( 1 == i )
{
SPMP_LCM_LightCtrl( LCM_LIGHT_DISABLE ); // 关掉系统的背光.
}
return;
}
/************************************************************************/
/* 控制EVB 电路的电源开关
input:
flag [in] UINT16
SPMP_POWER_OFF
SPMP_POWER_ON
output: void
func:
note:
如果是关闭系统电源, 程序不返回
*/
/************************************************************************/
void SPMP_PowerControl ( UINT16 flag )
{
UINT16 i;
i = 0;
if ( SPMP_POWER_OFF != flag) {
i ++;
}
#ifndef PMP3050_EVB_SN_V10
// set LCM GPIO 25 OUTPUT VALUE
set_reg_bit( REG_LCM_GPIO_OUTPUT_VALUE + LCM_GPIO_25/8, LCM_GPIO_25%8, i);
// set output enable
set_reg_bit( REG_LCM_GPIO_OUTPUT_ENABLE + LCM_GPIO_25/8, LCM_GPIO_25%8, 1);
// set LCM OUTPUT SELECT 1
set_reg_bit( REG_LCM_GPIO_OUTPUT_SELECT + LCM_GPIO_25/8, LCM_GPIO_25%8, 1);
if ( SPMP_POWER_OFF == flag) {
// disable pull high
set_reg_bit( REG_LCM_GPIO_PULL_ENABLE + LCM_GPIO_25/8, LCM_GPIO_25%8, 0);
}
#else
/*PMP3050_EVB_SN_V10 used HGPIO1 as Power_EN*/
//disable HGPIO1 input
set_reg_bit( REG_HGPIO_INPUT_ENABLE, 1, 0);
//enable HGPIO1 output
set_reg_bit( REG_HGPIO_OUTPUT_ENABLE, 1, 1);
//set HGPIO1 output value
set_reg_bit( REG_HGPIO_OUTPUT_VALUE, 1, i);
if ( SPMP_POWER_OFF == flag) {
// disable pull enable
set_reg_bit( REG_HGPIO_PULL_ENABLE, 1, 0);
}
#endif
while (1);
return;
}
/************************************************************************/
/* 获得当前热键的状态的数据
input:
void
output:
0 没有关机键 按下
非0值 关机键 按下
func:
获得当前热键的状态信息
*/
/************************************************************************/
UINT16 SPMP_Get_PowerStatus( void )
{
if ( gHotKeyStatus & 0x01 )
{
return APP_DRV_ERR; // 非0值表示 关机键被按下
}
return APP_DRV_OK; // 0 表示 有关机键被按下
}
/************************************************************************/
/* 将寄存器的某位进行置位或复位
input:
RegAddr [in] UINT32 32位的寄存器地址值
BitOffset [in] UINT16 0 ~ 7
Flag [in] UINT16 0 或者 非0值
output:
void
func:
*/
/************************************************************************/
static void set_reg_bit(UINT32 RegAddr, UINT16 BitOffset, UINT16 Flag)
{
UINT8 j;
UINT8 data;
// read data from register
data = READ8( RegAddr );
// 获得数据因子
j = 1 << BitOffset;
// 如果是"0", 进行清0 的动作
if (!Flag) {
j = ~j;
data &= j;
}
else{
data |= j;
}
// 将数据写回寄存器
WRITE8( RegAddr, data );
return;
}
/************************************************************************/
/* 启动键盘扫描程序
input:
viod
output:
void
func:
初始化键盘硬件端口的设置, 设定定时器程序
*/
/************************************************************************/
void SPMP_KeyDriverInit( void )
{
LastKey = DUMMY_KEY; // 上次的键值为空
gHotKeyStatus = 0x00; // 将热键状态清空
gSecondCount = SECOND_COUNT;
clr_PowerDown(); // set gPowerDown 0x00
#ifndef EVB_SN_V10
DEBUG_OUTPUT(("\r\n key driver for SUNPLUS\r\n"));
// 初始化键盘端口 (凌阳开发板)
key_port_initial();
#else
DEBUG_OUTPUT(("\r\n key driver for SUNNORTH\r\n"));
#ifndef SN_6047B
DEBUG_OUTPUT(("... EVB SN-6047\r\n"));
// 初始化键盘端口 (北阳开发板)
key_port_initial_snv10();
#else
DEBUG_OUTPUT(("... EVB SN-6047B\r\n"));
// 初始化键盘端口 (北阳开发板)
key_port_initial_sn6047b();
// 初始化功能端口
function_port_initial();
#endif
#endif
// 设定时的动作
tmrPeriodFuncSet(TIMER0, (void*)SPMP_KeyDriverTimerFunc, KEY_SCAN_PERIOD);
// 返回
return;
}
/************************************************************************/
/* 启动键盘任务的程序
*/
/************************************************************************/
void SPMP_KeyDriverTimerFunc( void )
{
osQuePost(keyDrvQ, (void*)0x55aa);
}
/************************************************************************/
/* key driver TASK
input:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -