Mstar平台SAR 口使用

SAR 口作为IC 的input 端,一般采集连续的电压值,然后根据区间划分转换成码值,基于
这一个特性,按键板,部分温控器件,光感器件可以使用该特性完成一个ADC转换的效
果。

  1. SAR 物理连接

在这里插入图片描述
在这里插入图片描述
如上面两图,是按键板的与芯片端的SAR 物理连接图,按键down 之后,产生的电压值
变化通过SAR 口进入芯片,驱动SAR 模块通过上层配置,来将不同电压区间 映射成对
应键值传递上去。

  1. SAR 口电压值与KeyCode映射
    MDrv_SYS_GlobalInit();
    mdrv_gpio_init();
	. . . . . .
    MDrv_MIU_SetIOMapBase();
    SAR_KpdRegCfg SARCfg;
    MDrv_SAR_Kpd_Init();

    int i, j;
    for (i = 0; i < MAX_KEYPAD_CH; i++) {
        if (BOARD_KPD[i].bEnable == false) {
            continue;
        }
        SARCfg.u8SARChID = BOARD_KPD[i].u8SARChID;
        SARCfg.tSARChBnd.u8UpBnd = BOARD_KPD[i].tSARChBnd.u8UpBnd;
        SARCfg.tSARChBnd.u8LoBnd = BOARD_KPD[i].tSARChBnd.u8LoBnd;
        SARCfg.u8KeyLevelNum = BOARD_KPD[i].u8KeyLevelNum;
        for (j = 0; j < 8; j++) {
            SARCfg.u8KeyThreshold[j] = BOARD_KPD[i].u8KeyThreshold[j];
            SARCfg.u8KeyCode[j] = BOARD_KPD[i].u8KeyCode[j];
        }
        //  将电压值的区间  和 对应 keycode 的映射关系(SARCfg.u8KeyThreshold ,SARCfg.u8KeyCode)
        //  设置到SAR 驱动里面
        if (MDrv_SAR_Kpd_SetChInfo(&SARCfg) == E_SAR_KPD_FAIL) {
            ALOGV("DFBInfo MDrv_SAR_Config: CH_%d fails\n", i);
            return FALSE;
        }
    }

MDrv_SAR_Kpd_SetChInfo 接口完成电压值和keycode 映射关系 的注册。

  1. SAR 口KeyCode事件获取

完成之后就可以监听获取按键板事件了,如下:

	while (1) {
		ret = E_SAR_KPD_FAIL;
		u8Keycode = NULL_KEYVALUE;
		u8Repeat = 0;

		/* sleep an interval time */
		usleep(keypad_input_interval);

		ret = MDrv_SAR_Kpd_GetKeyCode(&u8Keycode, &u8Repeat);

		/* check the get keycode successfully */
		if (ret != E_SAR_KPD_OK) {
			loop_count += 1;
			if (loop_count == SLOW_POLLING_BOUNDARY)
				keypad_input_interval = KEYPAD_INPUT_SLOW_POLLING;

			if (repeatKey != NULL_KEYVALUE) {
				write_event_to_device(repeatKey, 0);
				repeatKey = NULL_KEYVALUE;
			}
			continue;
		}
		/* check the keypad is vaild? */
		if (u8Keycode == NULL_KEYVALUE) {
			loop_count += 1;
			if (loop_count == SLOW_POLLING_BOUNDARY)
				keypad_input_interval = KEYPAD_INPUT_SLOW_POLLING;
			continue;
		}
		/* fill event to uinput device. */
		if (u8Repeat == 1) {
			repeatKey = u8Keycode;
		}
		write_event_to_device(u8Keycode, u8Repeat);
		loop_count = 0;
		keypad_input_interval = KEYPAD_INPUT_NORMAL_POLLING;
	}

MDrv_SAR_Kpd_GetKeyCode 接口可以获取到按键板按键的down 事件轮训周期间隔可
以自行设置。

  1. SAR 口通道设置和ADC值获取
        MDrv_SAR_Adc_Config(1, TRUE);
        adc1 = MDrv_SAR_Adc_GetValue(1);

MDrv_SAR_Adc_Config 接口来设置SAR 通道的开启和关闭,参数1 表示对应的参数id
从0 开始,参数2 TRUE/FALSE 分别 表示 开启/关闭 。
MDrv_SAR_Adc_GetValue 接口就是直接获取SAR 口外设产生的原始ADC值,也即是映射之前的原始值。M平台更多SAR口的操作方法参考libraries\utopia\include\drvSAR.h
文件。

注意:sar 通道必须根据原理图的实际连接进行设置,否则连接的外设无法使用。

  1. SAR 口应用实例
    通过SAR口上面的温控器件状态变化,来调节TCON板的属性。
void MSrv_Control_DVB::LUT_Monitor_Service(void)
{
    . . . . . .

    if((mapi_time_utility::GetTime0() - u32LutTimer) > 1000)
    {
        u32LutTimer = mapi_time_utility::GetTime0();
        // SAR 2 口的
        U8 u8ADCLevel = MSrv_Control::GetInstance()->GetSarAdcLevel(KEYPAD_ADC_CHANNEL_2);

        if ((u8PreCDegree > 0)
            && (u8ADCLevel >= stOsLutAdc[u8PreCDegree-1].u8TempFallingEdge))
        {
            for(int i=0; i<OS_LUT_MAX_C_DEGREE; i++)
            {
                if (u8ADCLevel >= stOsLutAdc[i].u8TempFallingEdge)
                {
                    u8CDegree = i;
                    break;
                }
            }
        }
        else if ((u8PreCDegree < OS_LUT_MAX_C_DEGREE-1)
            && (u8ADCLevel <= stOsLutAdc[u8PreCDegree+1].u8TempRisingEdge))
        {
            for(int i=OS_LUT_MAX_C_DEGREE-1; i>0; i--)
            {
                if (u8ADCLevel <= stOsLutAdc[i].u8TempRisingEdge)
                {
                    u8CDegree = i;
                    break;
                }
            }
        }
        else
        {
            u8CDegree = u8PreCDegree;
        }

        // 2nd step: Check V Sync
        U16 u16OutVFreq = MApi_XC_GetOutputVFreqX100();

        if (u16OutVFreq < 5500)
        {
            u8FPS = OS_LUT_FPS_50;
        }
        else
        {
            u8FPS = OS_LUT_FPS_60;
        }

        // 3rd step: Change OS LUT.
        if ((u8FPS != u8PreFPS)
            || (u8CDegree != u8PreCDegree))
        {
            MAPI_U8 *pu8SharpOsLutCtrlTab;
            MAPI_U32 u32SharpTconDevId;
            if (m_bIsSharpTconModel_Elan)
            {
                pu8SharpOsLutCtrlTab = u8SharpElanOsLutCtrlTab;
                u32SharpTconDevId = SHARP_ELAN_TCON_CTRL;
                u8SharpElanOsLutCtrlTab[3] = (U8)((u8SharpElanOsLutRegTab[u8FPS][u8CDegree]>>8)&0xFF);
                u8SharpElanOsLutCtrlTab[4] = (U8)(u8SharpElanOsLutRegTab[u8FPS][u8CDegree]&0xFF);
            }
            else
            {
                pu8SharpOsLutCtrlTab = u8SharpEspritOsLutCtrlTab;
                u32SharpTconDevId = SHARP_ESPRIT_TCON_CTRL;
                u8SharpEspritOsLutCtrlTab[3] = (U8)(u8SharpEspritOsLutRegTab[u8FPS][u8CDegree]&0xFF);
            }

            MAPI_U8 u8retryCnt = 0;
            do
            {
                if (MSrv_Control::GetInstance()->WriteBytesToI2C(u32SharpTconDevId, 2, pu8SharpOsLutCtrlTab+1, *pu8SharpOsLutCtrlTab, pu8SharpOsLutCtrlTab+3))
                {
                    pu8SharpOsLutCtrlTab += (*pu8SharpOsLutCtrlTab+1+2);
                    u8retryCnt = 0;
                }
                else
                {
                    u8retryCnt++;
                    if (u8retryCnt > 3)
                    {
                        printf("[%s]I2C Error: change OS Lut fail.\n", __FUNCTION__);
                        return;//break;
                    }
                }
            } while (*pu8SharpOsLutCtrlTab!=0);

            u8PreFPS = u8FPS;
            u8PreCDegree = u8CDegree;
        }
    }
}

先通过MSrv_Control::GetInstance()->GetSarAdcLevel 获取SAR 2 口的温控器件的ADC
值,接着计算转成TCON板的参数,MSrv_Control::GetInstance()->WriteBytesToI2C
接口再将TCON参数通过IIC 地址写到TCON上,来改变TCON板的状态。

U8 MSrv_Control_common::GetSarAdcLevel(U8 u8Channel)
{
    U8 u8Ret;
    u8Ret = mapi_sar::GetInstance()->GetSarAdcLevel(u8Channel);
    return u8Ret;
}

MAPI_U8 mapi_sar::GetSarAdcLevel(MAPI_U8 u8Channel)
{
    return m_pImpl->GetSarAdcLevel(u8Channel);
}

MAPI_U8 mapi_sar_impl::GetSarAdcLevel(MAPI_U8 u8Channel)
{
    MDrv_SAR_Adc_Config(u8Channel, MAPI_TRUE);
    usleep(50);//delay 0.05 ms here for getting the right adc level
    return MDrv_SAR_Adc_GetValue(u8Channel);
}

sar 模块的demo示例也可以查看DFBInfo.cpp。

另外,附上一张A平台ADC key 使用示例
在这里插入图片描述

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

猜你喜欢

转载自blog.csdn.net/kehyuanyu/article/details/97956870
sar
今日推荐