📄 pmp_key_task.c
字号:
void
output:
void
func:
扫描键盘端口, 如果有键按下, 获得键值, 向GUI发送消息
*/
/************************************************************************/
void SPMP_KeyDriverTask( void )
{
UINT32 osErr;
UINT16 ret;
UINT16 PhyKeyValue;
UINT16 GUIKeyValue;
UINT16 RepeatCount;
UINT32 holdkeystatus;
clr_PowerDown();
RepeatCount = REPEAT_KEY_COUNT;
keyDrvQ = osQueCreate("keyDrv queue", (void *)&keyDrvQueBuf[0], KEY_DRV_QUE_SIZE);
while (1)
{
// 等待信号的到来
osQuePend(keyDrvQ, OS_WAIT_FOREVER, &osErr);
// 只有在 PMP 的状态下,才会进行关机的处理
if ( STATUS_PMP_PROG == SPMP_Get_GameFlag() )
{
// 检查关机标志是否有效
if ( get_PowerDown() ){
if ( !power_off_detect()){
increase_PowerDown();
}
if ( get_PowerDown() >= RELEASE_COUNT ) { // 延迟一段时间进行关机
SPMP_SendGUIMessage((UINT8)MSG_OTHER,(UINT32)POWER_DOWN_DO, (UINT8)NULL);
clr_PowerDown();
}
continue;
}
}
// 对 耳机 是否接入, LCM 背光是否需要熄灭, 进行检测.
if (!gSecondCount) {
gSecondCount = SECOND_COUNT;
SPMP_HeadPhone_Detect(); // 对耳机接入的检测
process_powersave_period(); // 定时器对节电的处理
process_autooff_period(); // 定时对自动关机进行检测
process_lowpower_period(); //定时对低电关机进行检测
}
gSecondCount --;
if(0==SPMP_KeyScan_EnableStatusGet()){
continue;
}
//判断键盘是否被hold键锁住
holdkeystatus = SPMP_GetHoldKeyStatus();
if(1==holdkeystatus){
continue;
}
// 对开关机键进行扫描, 注意该键是复用.
if ( power_off_detect( ) )
{
nes_power_process( 0x01); // NES 处理 POWER DOWN
if ( STATUS_PMP_PROG == SPMP_Get_GameFlag() )
{
if ( gLongPushCount ){ // 如果计数值存在,进行递减
gLongPushCount --;
}
else{
increase_PowerDown(); // gPOwerDown ++
SPMP_SendGUIMessage((UINT8)MSG_OTHER,(UINT32)POWER_DOWN_PREPARE, (UINT8)NULL);
}
continue;
}
}
else{
nes_power_process( 0x00 ); // NES 处理 POWER 键 UP
}
gLongPushCount = ON_OFF_KEY_CNT; // 没有按下,直接将数值复位
PhyKeyValue = get_key_value_snv10(); // 进行键盘扫描处理,获得键值
// 如果本次键值为"空", 上次键值也为"空", 不作处理
if ( (LastKey == DUMMY_KEY) && (PhyKeyValue == DUMMY_KEY) ) {
continue;
}
// 对按键的重复处理, LastKey 为有效值, 本次也为有效值, 是上次的按键没有释放
if ( (LastKey != DUMMY_KEY) && ( DUMMY_KEY != PhyKeyValue) && RepeatCount )
{
RepeatCount --; // 通过设定 Repeat值,调解时间
continue;
}
RepeatCount = REPEAT_KEY_COUNT;
// 判断当前的状态, 如果是NES GAME, 进行游戏的按键处理
if ( STATUS_NES_GAME == SPMP_Get_GameFlag() ) {
nes_key_process( PhyKeyValue );
}
else{
// GUI 的相关处理流程
ret = gui_key_process( LastKey, PhyKeyValue );
if ( ret ) { continue; }
}
LastKey = PhyKeyValue; // 更新键值
process_powersave_key(); // 进行 LCM 背光的处理
process_autooff_key(); // 进行 自动关机的处理
}
}
/************************************************************************/
/* judge_gui_msg
input:
MSG [in] UINT16
MSG_KEYBOARD
MSG_KEYBOARD_UP
output:
0 不需要发送GUI 消息
非0值 需要向GUI 发送消息
func:
note:
*/
/************************************************************************/
static UINT16 judge_gui_msg( UINT16 msg )
{
if ( !gGUIMsgFlag ){
gGUIMsgFlag ++; // 将MSG 标志翻转过来
return 0x00; // 本次不需要消息
}
// 如果节电状态处于使能的状态,并且已经处于熄灭了
if ( (ENABLE_POWER_SAVE == SPMP_Get_PowerSaveFlag())
&& (!SPMP_Get_PowerSaveCount()
&& ( MSG_KEYBOARD == msg)))
{
gGUIMsgFlag = 0x00; // 需要将标志复位
return 0x00; // 不需要发送消息
}
return 0x01; // 其他方式返回为 1
}
/************************************************************************/
/* 输入一个字节的数据,和需要检查位数, 返回该数值中第一个"0"的位置
input:
data [in] 被测试的数据
len [in] 需要检测的长度
output:
如果没有找到 0 的存在, 返回 (-1)
func:
note:
*/
/************************************************************************/
static UINT16 get_zero_position( UINT32 data, UINT16 len )
{
UINT16 count;
UINT16 i;
UINT32 j;
j = 0x01;
count = 0x00;
for(i=0x00; i<len; i++, j <<= 1){
if (data & j) {
continue;
}
break;
}
if (i == len)
{
return 0xffff;
}
return i;
}
/************************************************************************/
/* 输入一个字节的数据,和需要检查位数, 返回该字节中 0 的个数
input:
data [in] 被测试的数据
len [in] 需要检测的长度
output:
返回该数据中"0"的个数
func:
note:
*/
/************************************************************************/
static UINT16 get_zero_bits( UINT32 data, UINT16 len )
{
UINT16 count;
UINT16 i;
UINT32 j;
j = 0x01;
count = 0x00;
for(i=0x00; i<len; i++, j <<= 1){
if (data & j) {
continue;
}
count ++;
}
return count;
}
/************************************************************************/
/* 将扫描得到的物理键值,转换为 GUI 能够识别的键值
input:
phy_value [in] 驱动层获得的扫描码
output:
*/
/************************************************************************/
static UINT16 phy2gui_value( UINT16 physical_value)
{
UINT16 i, ret;
ret = 0xffff;
// 检测输入的是否为正确键值
for( i=0x00;
i<sizeof(key_map_table)/sizeof(key_map_table[0]);
i++ )
{
if (key_map_table[i][0] == physical_value)
{
ret = key_map_table[i][1];
break;
}
}
return ret;
}
/************************************************************************/
/* 设定喇叭输出是否有声
input:
flag 0 无声
非0值 有声
output:
func:
*/
/************************************************************************/
UINT16 SPMP_Speaker_Set( UINT16 flag )
{
set_reg_bit( REG_GPIO_FINT_EN, IO_SPEAKER_MUTE, 0 );
set_reg_bit( REG_GPIO_RINT_EN, IO_SPEAKER_MUTE, 0 ); // disable interrupt
set_reg_bit( REG_GPIO_PULL_EN, IO_SPEAKER_MUTE, 1); // enable pull
set_reg_bit( REG_GPIO_OUTPUT_EN, IO_SPEAKER_MUTE, 1); // enable output
set_reg_bit( REG_GPIO_OUTPUT_VAL, IO_SPEAKER_MUTE, flag); // enable output
return 0;
}
/************************************************************************/
/* 初始化一些功能端口的设置
input:
void
output:
0 成功, 非0值失败
func:
初始化功能端口
note:
*/
/************************************************************************/
static void function_port_initial( void )
{
// UINT8 data;
set_reg_bit( REG_GPIO_FINT_EN, IO_POWER_DETECT, 0 );
set_reg_bit( REG_GPIO_RINT_EN, IO_POWER_DETECT, 0 ); // disable interrupt
set_reg_bit( REG_GPIO_PULL_EN, IO_POWER_DETECT, 0); // disbale pull
set_reg_bit( REG_GPIO_OUTPUT_EN, IO_POWER_DETECT, 0); // disbale output
#ifndef PMP3050_EVB_SN_V10
set_reg_bit( REG_GPIO_INPUT_EN, IO_POWER_DETECT, 1); // enable input
#else
/**sellect pin as gpio***/
set_reg_bit( REG_UART2_UART_EN, REG_UART2_UART_EN_BIT, 0);
set_reg_bit( REG_EN_UART, REG_EN_UART2_BIT, 0);
//ugpio14 used as power detect ,so bitoff = 14-8=6
UINT16 bitoff=6;
set_reg_bit( REG_UGPIO_15_8_INPUT_ENABLE, bitoff, 1); // enable input
set_reg_bit( REG_UGPIO_17_10_OUTPUT_ENABLE, bitoff, 0);// disbale output
#endif
return;
}
/************************************************************************/
/* 检测关机按键是否被按下
input:
void
output:
0 没有关机按键, 非0值 有关机键按下
func:
note:
北阳EVB上使用GPIO6 作为关机检测的引脚
*/
/************************************************************************/
static UINT16 power_off_detect( void )
{
UINT8 data;
// 如果不需要进行 关机键的扫描, 直接返回 0x00
if ( !SPMP_Get_ScanPowerKey() ){
return APP_DRV_OK;
}
// 读取端口的状态
#ifndef PMP3050_EVB_SN_V10
data = READ8( REG_GPIO_INPUT_VAL );
if ( data & (1<<IO_POWER_DETECT) )
#else
data = READ8( REG_UGPIO_17_10_INPUT_VALUE );
//ugpio14 used as power detect ,so bitoff = 14-10=4
if ( data & (1<<4) )
#endif
{
return APP_DRV_ERR; // 高电平, 表示键被按下
}
return APP_DRV_OK; // 低电平 没有按键
}
/************************************************************************/
/* 初始化 键盘扫描端口 的设置
input:
void
output:
void
func:
disable GPIO 上升沿 中断
disable GPIO 下降沿 中断
disable GPIO output 功能
enable pull-high
enable pull function
enable GPIO input
3 4 5 6 7 8 9 10 GND GPIO
----------------------------
---------------------------- GPIO
11 12 13 14 15 16 17 18
3 ......... 18
*/
/************************************************************************/
#ifndef EVB_SN_V10
/*
* 在台北大开发板上,使用 GPIO 作为 key port
*/
static void key_port_initial( void )
{
UINT8 Value;
UINT16 i;
UINT32 RegAddr;
#if 1
// disable
for(i=0x00; i<0x03; i++)
{
if(0 == i){
RegAddr = 0x10001130;
}
else if (1 == i) {
RegAddr = 0x10001138;
}
else{
RegAddr = 0x10001108;
}
// 3 - 7
Value = READ8(RegAddr);
Value &= 0x07;
WRITE8(RegAddr++, Value);
// 8 - 15
WRITE8(RegAddr++, 0x00);
// 16 - 18
Value = READ8(RegAddr);
Value &= 0xF8;
WRITE8(RegAddr++, Value);
}
for(i=0x00; i<0x03; i++)
{
if(0 == i){
RegAddr = 0x100001a4; // pull select
}
else if (1 == i) {
RegAddr = 0x100001c8; // pull enable
}
else{
RegAddr = 0x100001ec; // input enable
}
// 3 - 7
Value = READ8(RegAddr);
Value |= 0xf8;
WRITE8(RegAddr++, Value);
// 8 - 15
WRITE8(RegAddr++, 0xff);
// 16 - 18
Value = READ8(RegAddr);
Value |= 0x07;
WRITE8(RegAddr++, Value);
}
#else
/*
* GPIO register map table
*/
// disable GPIO falling edge interrupt
Value = 0x00;
RegAddr = 0x10001130;
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
// disable GPIO rising edge interrupt
Value = 0x00;
RegAddr = 0x10001138;
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
// disable GPIO output
Value = 0x00;
RegAddr = 0x10001108;
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
/*
* 0x1A4 - 0x1A6 Cpugpio pull set 0 - pull down 1 - pull high
*/
// select pull high
Value = 0xff;
RegAddr = 0x100001a4;
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
/*
* 0x1c8 - 0x1ca Cpugpio pull enable 0 - disable 1 - enable
*/
// enable pull function
Value = 0xff;
RegAddr = 0x100001c8;
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
/*
* 0x1ec - 0x1ee Cpugpio input enable 0 - disable 1 - enable
*/
Value = 0xff;
RegAddr = 0x100001ec;
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
WRITE8(RegAddr++, Value);
#endif
return;
}
#endif
/************************************************************************/
/* 在 SN-6047B 开发板上 键盘端口使用 4 - 21
*/
/************************************************************************/
static void key_port_initial_sn6047b( void )
{
UINT8 Value;
// UINT16 i;
UINT32 RegAddr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -