Mstar 648 平台遥控器/按键包POWER键配置

mstar 平台经常配置客户遥控器,客户提供遥控器后,一般我们需要拿到遥控器的头码,按键的物理码值表(头码配置后也可以getevent获取得到)。系统在运行过程中,一般有两个模块中需要对遥控器进行解码,系统运行过程中(kernel),系统待机过程中(PM)。所有我们需要在这个两个地方配置。

PM配置遥控器

由于PM 是机器待机过程中运行的一段小程序,响应一些唤醒源(遥控器,按键板,uart唤醒,wol唤醒,GPIO唤醒,CEC唤醒,HDMI唤醒),此处我们针对遥控器讲解。例如客户的头码是0xF708,在vendor\mstar\pm\zenonia\Project\Source\ir\IR_MSTAR_DTV.h,文件中:

#define IR_MODE_SEL           IR_TYPE_SWDECODE_MODE
// IR Header code define
#define IR_HEADER_CODE0         0x08    // Custom 0
#define IR_HEADER_CODE1         0xF7    // Custom 1

typedef enum _IrCommandType
{
    IRKEY_TV_ANTENNA        = 0x0C,
#ifndef ENABLE_DMP
    IRKEY_TV_RADIO          = 0x03,//same as IRKEY_PAGE_UP
#endif
    IRKEY_POWER             = 0xD7, //0x46,
	......
 };

IR_MODE_SEL指定IR解码方式为软解,IR_HEADER_CODE0 和IR_HEADER_CODE1指定遥控器的头码,分别低位和高位,IRKEY_POWER 配置power 键物理键值。配置好之后, 且待机前设置的待机参数包含该power 键值,这样待机之后才可以正常唤醒。

待机参数设置

待机参数设置,是在supernova 中完成,主要功能就是告诉PM ,在待机后,你可以相应哪些唤醒源,如果配置不对很有可能就无法唤醒。其实DC待机下,supernova 设置唤醒源参数进入待机,在PM 唤醒,这样就成了一个闭环。

1. SN下遥控器待机参数设置
文件vendor\mstar\supernova\MStarSDK\src\utility\mapi_types.h中

/// Define PM wake-up parameter
typedef struct DLL_PUBLIC
{
    /// For PM IR Wake-up
    MAPI_U8 bPmWakeEnableIR         : 1;
    /// For PM SAR Wake-up
    MAPI_U8 bPmWakeEnableSAR        : 1;
    /// For PM GPIO0 Wake-up
    MAPI_U8 bPmWakeEnableGPIO0      : 1;
    /// For PM GPIO1 Wake-up
    MAPI_U8 bPmWakeEnableGPIO1      : 1;
    /// For PM UART1 Wake-up
    MAPI_U8 bPmWakeEnableUART1      : 1;
    /// For PM SYNC Wake-up
    MAPI_U8 bPmWakeEnableSYNC       : 1;
    /// For PM EasySYNC Wake-up
    MAPI_U8 bPmWakeEnableESYNC      : 1;

    /// For PM RTC0 Wake-up
    MAPI_U8 bPmWakeEnableRTC0       : 1;
    /// For PM RTC1 Wake-up
    MAPI_U8 bPmWakeEnableRTC1       : 1;
    /// For PM DVI0 Wake-up
    MAPI_U8 bPmWakeEnableDVI0       : 1;
    /// For PM DVI1 Wake-up
    MAPI_U8 bPmWakeEnableDVI2       : 1;
    /// For PM CEC Wake-up
    MAPI_U8 bPmWakeEnableCEC        : 1;
    /// For PM AVLINK Wake-up
    MAPI_U8 bPmWakeEnableAVLINK     : 1;
    /// For PM WOL Wake-up
    MAPI_U8 bPmWakeEnableWOL        : 1;

    ///For PM IR Wake-up key define
    MAPI_U8 u8PmWakeIR[MAX_BUF_WAKE_IR];
    ///For PM IR Wake-up key 2 define
    MAPI_U8 u8PmWakeIR2[MAX_BUF_WAKE_IR2];
    ///For PM WOL Wake-up MAC Addr define
    MAPI_U8 u8PmWakeMACAddress[MAX_BUF_WAKE_MAC_ADDRESS];

    ///For STR Power Mode, defined in EN_PM_STR_MODE
    MAPI_U8 u8PmStrMode;
    ///For STR CRC check, TRUE for MIU1, FALSE for MIU0
    MAPI_BOOL bLxCRCMiu[CRC_KERNEL_BUF];
    ///For STR CRC check, memory address
    MAPI_U32 u32LxCRCAddress[CRC_KERNEL_BUF];
    ///For STR CRC check, memory size
    MAPI_U32 u32LxCRCSize[CRC_KERNEL_BUF];

} PM_WakeCfg_t;

typedef struct DLL_PUBLIC
{
    PM_WakeCfg_t stPMWakeCfg;
    PM_PowerDownCfg_t stPMPowerDownCfg;
} PM_Cfg_t;

PM_WakeCfg_t 里面bPmWakeEnableXXXX 使能对应的唤醒源,其中Wol 唤醒还需要设置有线网卡芯片的mac地址,遥控器唤醒的话就需要设置power 的物理键值。
文件vendor\mstar\supernova\projects\msrv\control\src\MSrv_Control_common.cpp下
MSrv_Control_common::GetPMCfg 函数中,会往 PM 中传入两个数组,当 PM 获取到的 IR 或者 Keypad的 Key code 值,与数组中对应时,就会响应唤醒动作。

MAPI_U8 u8PmWakeIRArray[] =
{
	//IR wake-up key define
	0xD0, powerkey, 0x98, 0x18,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF
};
MAPI_U8 u8PmWakeIRArray2[] =
{
	//IR wake-up key 2 define
	0x46, powerkey, u8PowerOnNetflixKey, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF
};

上面是公版某项目 supernova 传入 PM 的数组值. 0XFF 表示无效的值,
0xd0/power/, 0x98/CH+/, 0x18/CH-/.
这样在 PM 下,power,CH+,CH-都能响应唤醒功能。

2. SN下按键板待机参数设置
在supernova 中,MSrv_Control_common::PreBuildSystem::SetKEYPADCfg(); SetKeypadChInfo 函数会读取keypad.h 的参数,然后设置按键头码,keypad 的power 键值。

        pKeyCodePower =pEnvMan->GetEnv("power_key");
        if(pKeyCodePower != NULL)
        {
            KeyCodePower =(MAPI_U32) strtoul(pKeyCodePower, 0, 16);
        }
        
		void SetIRPowerupKeys()
		{
		    m_IRPowerupKey.keys = KeyCodePower;
		}

通过环境变量预置按键板的power键值。例如
Vendor_3697_Product_0002.kl

key 30   POWER             //  30 = 0x1E
key 35   HOME
key 48   TV_INPUT
key 50   VOLUME_DOWN
key 49   VOLUME_UP

set_config 文件中,

setenv  power_key 0x1E

如果是AC上电待机,则是有Mboot - -> PM,这个时候需要在mboot 里面来完成设置。
在vendor\mstar\mboot\MBoot\MstarCustomer\MSTAR\src\CusPM.c中SetPm2L1 函数里面设置完唤醒源后,然后进入PM,等待唤醒。

3. Mboot 下遥控器待机参数设置

#define POWER_KEY_NAME          "keypad_power_key"

    static PM_WakeCfg PmWakeCfg =
        {
            .bPmWakeEnableIR = TRUE,
#if (CONFIG_KEYPAD)
            .bPmWakeEnableSAR = TRUE,
#else
            .bPmWakeEnableSAR = FALSE,
#endif
            .bPmWakeEnableGPIO0 = FALSE,
            .bPmWakeEnableGPIO1 = FALSE,
            .bPmWakeEnableUART1 = FALSE,
            .bPmWakeEnableSYNC = FALSE,
            .bPmWakeEnableESYNC = FALSE,

            .bPmWakeEnableRTC0 = TRUE,
            .bPmWakeEnableRTC1 = TRUE,
            .bPmWakeEnableDVI0 = FALSE,
            .bPmWakeEnableDVI2 = FALSE,
            .bPmWakeEnableCEC = TRUE,
            .bPmWakeEnableAVLINK = FALSE,

            .u8PmWakeIR =
            {   //IR wake-up key define
                IRKEY_POWER, 0x03, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF
            },
            .u8PmWakeIR2 =
            {   //IR wake-up key define
                IRKEY_POWER, 0x03, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xFF, 0xFF, 0xFF
            }
        };
    char* s = getenv(POWER_KEY_NAME);
    if (s)
    {
        PmWakeCfg.u8PmWakeIR[0] = simple_strtoul(s, NULL, 16);
    }
    flush_cache((MS_U32)&PmWakeCfg, sizeof(PM_WakeCfg));
    if(MDrv_PM_Init((PM_WakeCfg*)VA2PA((MS_U32) &PmWakeCfg))==0)

PmWakeCfg.u8PmWakeIR[0] 通过“keypad_power_key” 环境变量的值来设置遥控器power键值,然后通过MDrv_PM_Init 设置到PM里面,接着进入PM。

4. Mboot 下按键板待机参数设置

BOOLEAN msAPI_KeyPad_Initialize(void)
{
    UBOOT_TRACE("IN\n");
    static SAR_RegCfg sarRegCfgCh;
    SAR_RegCfg* psarRegCfgCh=&sarRegCfgCh;
    ......
    if(MDrv_SAR_Init()==E_SAR_FAIL)  // sar 口初始化
    {
		......
    }

    char* s = getenv("power_key");
    MS_U8 u8PowerKey = (NULL != s) ? simple_strtoul(s, NULL, 16) : IRKEY_DUMY;

    for(u8Idx = 0, k = 0; k < MAXKEYPADCH; k++)
    {
        if(m_KpdConfig[k].bEnable == ENABLE)
        {
            psarRegCfgCh->u8SARChID = k;
            psarRegCfgCh->u8UpBnd = m_KpdConfig[k].tSARChBnd.u8UpBnd;
            psarRegCfgCh->u8LoBnd = m_KpdConfig[k].tSARChBnd.u8LoBnd;
            psarRegCfgCh->u8KeyLevelNum = m_KpdConfig[k].u8KeyLevelNum;
            for(i = 0; i < psarRegCfgCh->u8KeyLevelNum; i++)
            {
                psarRegCfgCh->u8KeyThreshold[i] = m_KpdConfig[k].u8KeyThreshold[i];
                psarRegCfgCh->u8KeyCode[i] = m_KpdConfig[k].u8KeyCode[i];
            }

            if (IRKEY_DUMY != u8PowerKey)
            {
                for (i = 0; i < psarRegCfgCh->u8KeyLevelNum; ++i)
                {
                    if (IRKEY_POWER == psarRegCfgCh->u8KeyCode[i])
                    {
                        // keypad.h 中 ==  0x46,重复赋值为环境变量power_key的值
                        psarRegCfgCh->u8KeyCode[i] = u8PowerKey;
                    }
                }
            }

            ......

            if(MDrv_SAR_Config((SAR_RegCfg*)_VA2PA((MS_U32)psarRegCfgCh))==E_SAR_FAIL)
            {
                ......
            }

            if((++u8Idx) >= MAX_ADC_KEY_CHANNEL_NUM)
                break;
        }
    }

    if(MDrv_SAR_Enable(TRUE)==E_SAR_FAIL)
    {
        ......
    }

    return MSRET_OK;
}

将"power_key" 的值覆盖按键板的power 键键值。MDrv_SAR_Config 将按键的sar 值设置到PM里面。

Kernel 遥控器配置

配置遥控类型选择
vendor\mstar\kernel\linaro\mstar2\hal\mooney\cpu\arm64\board\BD_GENERIC.h

//------Peripheral Device Setting----------------------------
#ifndef IR_TYPE_SEL
#define IR_TYPE_SEL                 IR_TYPE_CUS21SH//IR_TYPE_MSTAR_DTV
#endif

IR_TYPE_SEL 定义的类型为IR_TYPE_CUS21SH 类型。接着在对应文件定义头码。

vendor\mstar\kernel\linaro\mstar2\drv\ir\IR_MSTAR_CUS21SH.h

//  解码方式设置
#define IR_MODE_SEL             IR_TYPE_SWDECODE_MODE   

// IR Header code define
#define IR_HEADER_CODE0         0x08UL    // Custom 0     //0x04
#define IR_HEADER_CODE1         0xF7UL    // Custom 1     //0xFB

vendor\mstar\kernel\linaro\drivers\media\rc\keymaps\rc-mstar-tv.c
vendor\mstar\kernel\linaro\drivers\media\rc\keymaps\rc-cultraview-tv-baseline.c

static struct rc_map_table mstar_tv[] = {
    { 0xf7d7, KEY_POWER },
    .....
 };

按键的键值就配置在rc_map_table 映射表中。
配置好头码后,通过getevent 获取键值。
在这里插入图片描述

发布了101 篇原创文章 · 获赞 19 · 访问量 33万+

猜你喜欢

转载自blog.csdn.net/kehyuanyu/article/details/100582282