?? pmp_key_task.c
字號(hào):
static UINT16 LastKey;
// key TASK 的序列
static UINT32 keyDrvQueBuf[KEY_DRV_QUE_SIZE];
// 定時(shí)器進(jìn)行按鍵的處理
static void process_powersave_period( void );
// 按鍵對節(jié)電模式的處理
static void process_powersave_key( void );
static UINT32 SPMP_KeyScan_Enable_Flag=1;
extern UINT32 g_uiStartFlag; //add for nes game
/*
* 物理按鍵 和 GUI 消息的對應(yīng)表 (用戶可以修改)
*/
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 根據(jù) 5K 鍵盤對應(yīng)關(guān)系進(jìn)行整理
{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},
};
/*
* 按鍵與按鍵音轉(zhuǎn)換表 (用戶可以修改)
*/
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 內(nèi)在鍵值的對應(yīng)表格 (用戶可以修改)
*/
#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 }, // 按鍵的釋放動(dòng)作, 用戶不能改動(dòng)
{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 ++
// 定時(shí)器對自動(dòng)關(guān)機(jī)的處理
static void process_autooff_period( void );
// 按鍵對自動(dòng)關(guān)機(jī)的處理
static void process_autooff_key( void );
// 檢測 關(guān)機(jī)鍵是否被按下
static UINT16 power_off_detect( void );
// 初始化 功能端口
static void function_port_initial( void );
#ifndef EVB_SN_V10
static void key_port_initial( void );// 初始化 鍵盤端口的 硬件設(shè)置 ( S+MM開發(fā)板)
static UINT16 get_key_value( void ); // 獲得鍵盤端口的值 (S+MM EVB )
#endif
// 初始化 鍵盤端口的 硬件設(shè)置 ( 北陽 開發(fā)板 V10 )
//static void key_port_initial_snv10( void );
// 北陽 SN-6047B 開發(fā)板的初始化程序
static void key_port_initial_sn6047b( void );
// 掃描端口的值( SN EVB V10)
static UINT16 get_key_value_snv10( void );
// 檢查一個(gè)數(shù)據(jù)中 "0" 的個(gè)數(shù)
static UINT16 get_zero_bits( UINT32 data, UINT16 len );
// 輸入一個(gè)數(shù)值和需要檢查的位數(shù), 返回第一個(gè)0的在該數(shù)值中的偏移值
static UINT16 get_zero_position( UINT32 data, UINT16 len );
// 將鍵盤掃描碼 轉(zhuǎn)換為 GUI 能夠識(shí)別的鍵值編碼
static UINT16 phy2gui_value( UINT16 physical_value);
// 啟動(dòng)鍵盤任務(wù)的程序
void SPMP_KeyDriverTimerFunc( void );
static void set_reg_bit(UINT32 RegAddr, UINT16 BitOffset, UINT16 Flag);
//獲取鍵掃描開啟/關(guān)閉狀態(tài)
UINT32 SPMP_KeyScan_EnableStatusGet(void);
// 關(guān)掉系統(tǒng)電源
void SPMP_PowerControl ( UINT16 flag );
// 設(shè)定和獲得 是否需要進(jìn)行POWER 鍵的掃描
extern void SPMP_Set_ScanPowerKey( UINT16 value );
extern UINT16 SPMP_Get_ScanPowerKey( void );
// 判斷是否需要進(jìn)行GUI 消息的發(fā)送
static UINT16 judge_gui_msg( UINT16 msg );
// 內(nèi)部函數(shù) NES 鍵盤的處理
static UINT16 nes_key_process( UINT16 key_value );
// 內(nèi)部函數(shù) GUI 鍵盤的處理
static UINT16 gui_key_process( UINT16 LastKey, UINT16 PhyKeyValue );
// 獲得 POWER 是否被按下的狀況
static UINT16 get_power_key_status( void );
// 設(shè)置 POWER 是否被按下的狀況
static void set_power_key_status( UINT16 data );
// 在 NES狀態(tài)下對 POWER 鍵的處理
static void nes_power_process( UINT16 data );
// 將一個(gè)物理鍵值轉(zhuǎn)換為NES 鍵值
static UINT32 phy_2_nes_key( UINT16 phy_key );
extern UINT32 SPMP_GetPwrStatus( void);
static void process_lowpower_period( void );
/************************************************************************/
/* 輸入一個(gè)按鍵值, 得到按鍵音的位置索引值
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);
}
/************************************************************************/
/* 設(shè)定是否需要進(jìn)行開關(guān)機(jī)鍵的掃描
input:
value 0 不需要掃描
非0值需要進(jìn)行掃描
output:
void
*/
/************************************************************************/
void SPMP_Set_ScanPowerKey( UINT16 value )
{
gScanPowerKey = value;
return;
}
UINT16 SPMP_Get_ScanPowerKey( void )
{
return gScanPowerKey;
}
/************************************************************************/
/* 設(shè)定自動(dòng)關(guān)機(jī)計(jì)數(shù)器的值
input:
value [in] UINT32
output:
void
func:
*/
/************************************************************************/
void SPMP_Set_AutoOffCnt(UINT32 value)
{
gBakAutoOffCount = value; // 備份值
gNowAutoOffCount = value; // 當(dāng)前值
return;
}
/************************************************************************/
/* 鍵盤對節(jié)電的處理
input:
output:
func: 按鍵對節(jié)電模式的處理
note:
*/
/************************************************************************/
static void process_powersave_key( void )
{
// 如果是 不需要進(jìn)行節(jié)電,直接返回
if ( DISABLE_POWER_SAVE == SPMP_Get_PowerSaveFlag() ) {
return;
}
// 如果當(dāng)前計(jì)數(shù)值為0, 說明已經(jīng)熄滅掉了
if( !SPMP_Get_PowerSaveCount() )
{
SPMP_LCM_LightCtrl( LCM_LIGHT_ENABLE ); // 點(diǎn)亮屏幕的背光
}
SPMP_Reset_PowerSaveCount(); // 將當(dāng)前的節(jié)電值進(jìn)行復(fù)位
return;
}
/************************************************************************/
/* 定時(shí)對自動(dòng)關(guān)機(jī)進(jìn)行檢測
input:
output:
func:
note:
*/
/************************************************************************/
static void process_autooff_period( void )
{
// 如果是禁止自動(dòng)關(guān)機(jī), 返回不用處理
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 --; // 計(jì)數(shù)值減一
}
else
{
increase_PowerDown(); // gPowerDown ++
#ifdef KEY_DEBUG_1211
DEBUG_OUTPUT(("\r\n自動(dòng)關(guān)機(jī), 發(fā)送消息!\r\n"));
#endif
SPMP_SendGUIMessage((UINT8)MSG_OTHER,(UINT32)POWER_DOWN_PREPARE, (UINT8)NULL);
}
return;
}
/*
* 按鍵對自動(dòng)關(guān)機(jī)的處理, 每次收到自動(dòng)關(guān)機(jī)后, 復(fù)位計(jì)數(shù)值
*/
static void process_autooff_key( void )
{
gNowAutoOffCount = gBakAutoOffCount; // 使用備份值
return;
}
/************************************************************************/
/* 定時(shí)對進(jìn)行節(jié)電的處理
input:
output:
func:
*/
/************************************************************************/
static void process_powersave_period( void )
{
UINT16 i;
// 如果是 不需要進(jìn)行節(jié)電,直接返回成功
if ( DISABLE_POWER_SAVE == SPMP_Get_PowerSaveFlag() ) {
return;
}
// 獲取當(dāng)前的計(jì)數(shù)值
i = SPMP_Get_PowerSaveCount();
if(!i){ // 如果已經(jīng)是 0 了,直接返回, 不需要繼續(xù)處理
return;
}
// 計(jì)數(shù)值減一
SPMP_Dec_PowerSaveCount();
if ( 1 == i )
{
SPMP_LCM_LightCtrl( LCM_LIGHT_DISABLE ); // 關(guān)掉系統(tǒng)的背光.
}
return;
}
/************************************************************************/
/* 控制EVB 電路的電源開關(guān)
input:
flag [in] UINT16
SPMP_POWER_OFF
SPMP_POWER_ON
output: void
func:
note:
如果是關(guān)閉系統(tǒng)電源, 程序不返回
*/
/************************************************************************/
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;
}
/************************************************************************/
/* 獲得當(dāng)前熱鍵的狀態(tài)的數(shù)據(jù)
input:
void
output:
0 沒有關(guān)機(jī)鍵 按下
非0值 關(guān)機(jī)鍵 按下
func:
獲得當(dāng)前熱鍵的狀態(tài)信息
*/
/************************************************************************/
UINT16 SPMP_Get_PowerStatus( void )
{
if ( gHotKeyStatus & 0x01 )
{
return APP_DRV_ERR; // 非0值表示 關(guān)機(jī)鍵被按下
}
return APP_DRV_OK; // 0 表示 有關(guān)機(jī)鍵被按下
}
/************************************************************************/
/* 將寄存器的某位進(jìn)行置位或復(fù)位
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 );
// 獲得數(shù)據(jù)因子
j = 1 << BitOffset;
// 如果是"0", 進(jìn)行清0 的動(dòng)作
if (!Flag) {
j = ~j;
data &= j;
}
else{
data |= j;
}
// 將數(shù)據(jù)寫回寄存器
WRITE8( RegAddr, data );
return;
}
/************************************************************************/
/* 啟動(dòng)鍵盤掃描程序
input:
viod
output:
void
func:
初始化鍵盤硬件端口的設(shè)置, 設(shè)定定時(shí)器程序
*/
/************************************************************************/
void SPMP_KeyDriverInit( void )
{
LastKey = DUMMY_KEY; // 上次的鍵值為空
gHotKeyStatus = 0x00; // 將熱鍵狀態(tài)清空
gSecondCount = SECOND_COUNT;
clr_PowerDown(); // set gPowerDown 0x00
#ifndef EVB_SN_V10
DEBUG_OUTPUT(("\r\n key driver for SUNPLUS\r\n"));
// 初始化鍵盤端口 (凌陽開發(fā)板)
key_port_initial();
#else
DEBUG_OUTPUT(("\r\n key driver for SUNNORTH\r\n"));
#ifndef SN_6047B
DEBUG_OUTPUT(("... EVB SN-6047\r\n"));
// 初始化鍵盤端口 (北陽開發(fā)板)
key_port_initial_snv10();
#else
DEBUG_OUTPUT(("... EVB SN-6047B\r\n"));
// 初始化鍵盤端口 (北陽開發(fā)板)
key_port_initial_sn6047b();
// 初始化功能端口
function_port_initial();
#endif
#endif
// 設(shè)定時(shí)的動(dòng)作
tmrPeriodFuncSet(TIMER0, (void*)SPMP_KeyDriverTimerFunc, KEY_SCAN_PERIOD);
// 返回
return;
}
/************************************************************************/
/* 啟動(dòng)鍵盤任務(wù)的程序
*/
/************************************************************************/
void SPMP_KeyDriverTimerFunc( void )
{
osQuePost(keyDrvQ, (void*)0x55aa);
}
/************************************************************************/
/* key driver TASK
input:
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -