📄 pmp_key_task_new.c
字号:
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:
void
output:
void
func:
扫描键盘端口, 如果有键按下, 获得键值, 向GUI发送消息
*/
/************************************************************************/
void SPMP_KeyDriverTask( void )
{
UINT32 osErr;
UINT16 i,ret;
UINT16 PhyKeyValue;
UINT16 GUIKeyValue;
UINT16 RepeatCount;
UINT32 holdkeystatus;
UINT32 LastBitMap, NowBitMap;
UINT16 LogKeyCnt;
UINT16 LogKeyBuf[0x10];
UINT16 HeadPhoneDetectCnt = 0x00; // [02/28/2007] lanzhu add
LastBitMap = 0x00; // 上次的 key bitmap
NowBitMap = 0x00; // 当前的 key bitmap
LogKeyCnt = 0x00; // 当前的 key 数量
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 ( !SPMP_Power_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;
// [02/28/2007] SN lanzhu add
HeadPhoneDetectCnt ++;
/*
if ( HeadPhoneDetectCnt >= 0x02 )
{
HeadPhoneDetectCnt = 0x00;
SPMP_HeadPhone_Detect(); // 对耳机接入的检测
}*/
process_powersave_period(); // 定时器对节电的处理
process_autooff_period(); // 定时对自动关机进行检测
process_lowpower_period(); //定时对低电关机进行检测
}
// [03/07/2007] lanzhu add for earphone detect
if(HeadPhoneDetectCnt >= 0x02)
{
SPMP_HeadPhone_Detect(); // 对耳机接入的检测
HeadPhoneDetectCnt ++;
if(HeadPhoneDetectCnt >0x06 )
{
HeadPhoneDetectCnt = 0x00;
}
}
gSecondCount --;
if(0==SPMP_KeyScan_EnableStatusGet()){
continue;
}
//判断键盘是否被hold键锁住
holdkeystatus = SPMP_GetHoldKeyStatus();
if(1==holdkeystatus){
continue;
}
// 对开关机键进行扫描, 注意该键是复用.
if ( SPMP_Power_Detect( ) )
{
// POWER 键也可以点亮背光
process_powersave_key();
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; // 没有按下,直接将数值复位
// 进行物理键盘的扫描, 获得当前的BITMAP
SPMP_KEY_PhyScan( &NowBitMap );
// 使用当前的状态 和 上次的状态, 获得 当前逻辑键值
LogKeyCnt = key_status_process( LastBitMap, NowBitMap, LogKeyBuf );
// 没有按键的情形, 继续循环
if ( !LogKeyCnt ) { continue; }
if ( STATUS_PMP_PROG == SPMP_Get_GameFlag())
{
#ifndef BIG_APPLE
// 在PMP 状态下, 如果有多个按键, 不进行处理
if ( LogKeyCnt>1) { continue; }
// [02/03/2007] lanzhu ahcnged
i = 1 <<( LogKeyBuf[0]&0xff);
// 在PMP 状态下, 不支持 REPAET功能, 如果先后 2个状态一致, 不进行处理
if ( (LastBitMap&i) == (NowBitMap&i)){ continue; }
#endif
// GUI 对逻辑键值进行处理
new_gui_key_process( LogKeyBuf[0] );
}
else{
// NES 游戏对按键的处理
new_nes_key_process( LogKeyCnt, LogKeyBuf );
}
LastBitMap = NowBitMap; // !!! 一定要进行更新
process_autooff_key(); // 进行 自动关机的处理
process_powersave_key(); // 只要有键按下,就可以点亮背光.
}
}
/************************************************************************/
/* judge_gui_msg
input:
MSG [in] UINT16
MSG_KEYBOARD
MSG_KEYBOARD_UP
output:
0 不需要发送GUI 消息
非0值 需要向GUI 发送消息
func:
history:
[01/28/2007] lanzhu add for 按键的匹配检查
*/
/************************************************************************/
static UINT16 judge_gui_msg( UINT16 msg )
{
UINT16 i;
#ifdef BIG_APPLE
// 判断是否上次只是点亮了背光
if ( !(gGUIMsgFlag&BIT_LIGHT_MASK) )
{
gGUIMsgFlag |= BIT_LIGHT_MASK;
return 0x00; // 不发送GUI MSG
}
// 省电状态处于使能 && 已经处于熄灭 && DOWN 键, 进行背光的点亮
if ( (ENABLE_POWER_SAVE == SPMP_Get_PowerSaveFlag())
&& (!SPMP_Get_PowerSaveCount())&& ( MSG_KEYBOARD== msg))
{
gGUIMsgFlag &= ~BIT_LIGHT_MASK;
//sio_printf("gGUIMsgFlag=%x\r\n",gGUIMsgFlag);
return 0x00; // 不发送GUI MSG
}
if(msg == 0xff)
{
return 0x00;
}
#else
// 判断是否上次只是点亮了背光
if ( !(gGUIMsgFlag&BIT_LIGHT_MASK) )
{
gGUIMsgFlag |= BIT_LIGHT_MASK;
return 0x00; // 不发送GUI MSG
}
// 省电状态处于使能 && 已经处于熄灭 && DOWN 键, 进行背光的点亮
if ( (ENABLE_POWER_SAVE == SPMP_Get_PowerSaveFlag())
&& (!SPMP_Get_PowerSaveCount()
&& ( MSG_KEYBOARD == msg)))
{
gGUIMsgFlag |= BIT_LIGHT_MASK;
return 0x00; // 不发送GUI MSG
}
// 获得 当前的状态
i = gGUIMsgFlag&BIT_UPDOWN_MASK;
// [01/28/2007] 进行按键的匹配检查
if( !i ){ // 上次为 UP 状态
if ( MSG_KEYBOARD_UP == msg ){
return 0x00; // 本次是释放状态, 不作处理
}
else{
gGUIMsgFlag |= BIT_UPDOWN_MASK; // DOWN 键, 设置状态为DOWN
return 0x01;
}
}
else{
// DOWN 状态
gGUIMsgFlag &= ~BIT_UPDOWN_MASK; // 前面的程序有保证, 一定会是UP键, 转换为UP状态
}
#endif
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:
*/
/************************************************************************/
#ifndef NEW_IO_DEBUG
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;
}
#endif
/************************************************************************/
/* 初始化一些功能端口的设置
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -