Panel开发参考

Version 1.0


1. 配置屏参


1.1. 屏参配置文件介绍

屏参配置文件在alkaid中的路径为project/board/ini/misc/config.ini

系统启动过程中会去解析屏参配置文件,然后将不同屏参保存到系统中,给显示模块使用。

显示模块会根据用户调用API的参数设定向系统获取所需屏参。

屏参配置文件由section、variable name组成:

section:文件中方括号中的字段

variable name:文件中等号左边的字段,等号右边是给variable name赋的值

配置文件中section是唯一的,不允许存在同名section,但是允许存在同名variable name,比如上图中的section DACOUT_576I只能有一个,但是m_pPanelName可以出现在不同的section中。这样系统可以根据不同的section来区分variable name,然后就可以添加不同的屏参。

variable name的字段是系统中预先定义好的,在添加新的屏参时,只能填写系统中现有的variable name字段,新增或者修改variable name需要告知相关owner,否则系统无法识别,比如m_pPanelName这个variable name,在新增屏参时只能使用m_pPanelName去定义新的panel name。

在给variable name赋值时,如果value需要换行,可以在行尾加'\'作为换行符,如果variable name的value有多个,可以用{}将所有的value括起来,并且每个value后加逗号来表示该字段结束。如下图所示:

注意:新增屏参之后,需同步把m_pnlList = {}里面的更改为要点的屏的section name。


1.2. 屏参配置文件介绍

  1. 给新的屏参定义一个section name,可以随意定义但是不能和现有section name相同

  2. 将新的屏参section name追加到ROOT section中的m_pnlList变量中(不同接口的LCD section只能存在一个,比如m_pnlList中已经存在一个TTL的panel section name,那么如果想要添加新的TTL,只能删除掉之前存在的section)

  3. 将新的屏参参数添加到新的section中,如下:


2. 屏参数说明


2.1. 屏参数各项详细说明

参数 描述
m_pPanelName panel name
m_bPanelDither 1:enable Dither
0:disable Dither
m_ePanelLinkType 接口类型 TTL :0 MIPI_DSI :10
m_bPanelInvDCLK Pixel clk极性反转
m_bPanelInvDE DE极性反转
m_bPanelInvHSync Hsync极性反转
m_bPanelInvVSync Vsync极性反转
m_wPanelHSyncWidth 行同步信号脉宽
m_wPanelHSyncBackPorch 行同步信号后肩
m_wPanelVSyncWidth 场同步信号脉宽
m_wPanelVBackPorch 场同步信号后肩
m_wPanelHStart m_wPanelHSyncWidth+m_wPanelHSyncBackPorch
m_wPanelVStart m_wPanelVSyncWidth+ m_wPanelVBackPorch
m_wPanelWidth 行有效像素点数
m_wPanelHeight 场有效行数
m_wPanelHTotal m_wPanelWidth+m_wPanelHSyncWidth+m_wPanelHSyncBackPorch+HsyncFrontPorch
m_wPanelVTotal m_wPanelHeight+m_wPanelVSyncWidth+ m_wPanelVBackPorch+VsyncFrontPorch
m_wPanelDCLK m_wPanelHTotal*m_wPanelVTotal*fps(IP内部使用clk)
m_wSpreadSpectrumFreq 时钟延展幅度调制(详见展频计算表
m_wSpreadSpectrumRatio 时钟延展频率调制(详见展频计算表
m_eOutputFormatBitMode 10BIT :0 6BIT :1 8BIT :2 565BIT :3
m_ucPanelSwapChnR Swap Channel R
0:default
1:select R 
2:select G
3:select B
m_ucPanelSwapChnG Swap Channel G
0:default
1:select R 
2:select G
3:select B
m_ucPanelSwapChnB Swap Channel B
0:default
1:select R 
2:select G
3:select B
m_ucPanelSwapRgbML Swap Rgb MSB/LSB
0:disable M/L swap
1:enable M/L swap

2.2. 如何配置屏参数

根据屏规格书填写屏参。在屏规格书中找到Timing相关部分,如下表定义。

屏规格书中Timing定义和屏参参数对应如下表所示。

m_wPanelHSyncWidth HSYNC period time
m_wPanelHSyncBackPorch 参考HSYNC blanking的要求 根据上表,如果HSYNC blanking为320,那么m_wPanelHSyncBackPorch要小于320,差值部分为hsync front porch大小
m_wPanelVSyncWidth VSYNC period time
m_wPanelVBackPorch 参考VSYNC blanking的要求 根据上表,如果VSYNC blanking为35,那么m_wPanelVBackPorch要小于35,差值部分为vsync front porch大小
m_wPanelHStart m_wPanelHSyncWidth+m_wPanelHSyncBackPorch
m_wPanelVStart m_wPanelVSyncWidth+ m_wPanelVBackPorch
m_wPanelWidth Horizonial display area 
m_wPanelHeight Vertical display area
m_wPanelHTotal m_wPanelWidth+HSYNC blanking
m_wPanelVTotal m_wPanelHeight+VSYNC blanking
m_wPanelDCLK m_wPanelHTotal*m_wPanelVTotal*fps

如果是MIPI panel,还需要配置MIPI AC timing相关参数,首先在panel规格书中找到。


3. 如何点亮屏


3.1. 屏参配置

按照步骤1和2的说明,把project/board/ini/misc/config.ini里面的屏参增加好。


3.2. 屏初始化

参考:sdk/verify/mi_demo/source/panel/ st_main_panel.cpp

3.2.1. 宏定义说明

3.2.2. Panel start流程说明

MI_U32 ST_PanelStart(void)
{
    ST_Panel_Attr_T *pstPanelAttr = g_stPanelAttr;

    MI_DISP_DEV DispDev = 0;
    MI_U32 u32DispWidth = pstPanelAttr->u32Width; // 屏的width
    MI_U32 u32DispHeight = pstPanelAttr->u32Height; // 屏的height

    MI_PANEL_IntfType_e eLinkType = E_MI_PNL_INTF_TTL; // linktype,和platform有关联,根据实际platform的参数决定

    /************************************************
    Step0:  panel spi cmd init(by panel request)
    *************************************************/
    ST_Spi_CommandStart();// 如果需要SPI 通讯驱动的屏,需进行这步骤

    /************************************************
    Step1:  panel init
    *************************************************/
    STCHECKRESULT(MI_PANEL_Init(eLinkType)); // 芯片端的panel模块初始化

    /************************************************
    Step2:  set disp pub 
    *************************************************/
    MI_DISP_PubAttr_t stPubAttr;
    memset(&stPubAttr, 0x0, sizeof(MI_DISP_PubAttr_t)); // 芯片端显示模块初始化,显示到屏上的内容从disp送给panel

    stPubAttr.u32BgColor = YUYV_BLACK;
    stPubAttr.eIntfType = E_MI_DISP_INTF_TTL;
    stPubAttr.eIntfSync =  E_MI_DISP_OUTPUT_USER;
    STCHECKRESULT(MI_DISP_SetPubAttr(DispDev,  &stPubAttr));
    STCHECKRESULT(MI_DISP_Enable(DispDev));

    /************************************************
    Step3:  set layer
    *************************************************/
    MI_DISP_LAYER            DispLayer = 0;
    MI_SYS_PixelFormat_e     ePixFormat = E_MI_SYS_PIXEL_FRAME_YUV_SEMIPLANAR_420;  
    MI_DISP_VideoLayerAttr_t stLayerAttr;


    memset(&stLayerAttr, 0x0, sizeof(MI_DISP_VideoLayerAttr_t));

    stLayerAttr.stVidLayerDispWin.u16X = 0;
    stLayerAttr.stVidLayerDispWin.u16Y = 0;
    stLayerAttr.stVidLayerDispWin.u16Width = u32DispWidth;
    stLayerAttr.stVidLayerDispWin.u16Height = u32DispHeight;

    stLayerAttr.stVidLayerSize.u16Width = u32DispWidth;
    stLayerAttr.stVidLayerSize.u16Height = u32DispHeight;

    stLayerAttr.ePixFormat = ePixFormat;

    STCHECKRESULT(MI_DISP_BindVideoLayer(DispLayer,DispDev));
    STCHECKRESULT(MI_DISP_SetVideoLayerAttr(DispLayer, &stLayerAttr));
    STCHECKRESULT(MI_DISP_EnableVideoLayer(DispLayer));

    /************************************************
    Step4:  set inputport
    *************************************************/
    MI_U8 u8DispInport = 0;

    MI_DISP_InputPortAttr_t stInputPortAttr;
    MI_DISP_VidWinRect_t stWinRect;

    memset(&stWinRect, 0x0, sizeof(MI_DISP_VidWinRect_t));
    memset(&stInputPortAttr, 0x0, sizeof(MI_DISP_InputPortAttr_t));

    stInputPortAttr.stDispWin.u16X = 0;
    stInputPortAttr.stDispWin.u16Y = 0;
    stInputPortAttr.stDispWin.u16Width =u32DispWidth;
    stInputPortAttr.stDispWin.u16Height = u32DispHeight;

    stInputPortAttr.u16SrcWidth =u32DispWidth;
    stInputPortAttr.u16SrcHeight = u32DispHeight;

    stWinRect.u16Width = u32DispWidth;
    stWinRect.u16Height = u32DispHeight;


    printf("%s:%d layer:%d port:%d srcwidth:%d srcheight:%d x:%d y:%d outwidth:%d outheight:%d\n",__FUNCTION__,__LINE__,
        DispLayer,u8DispInport,
        stInputPortAttr.u16SrcWidth,stInputPortAttr.u16SrcHeight,
        stInputPortAttr.stDispWin.u16X,stInputPortAttr.stDispWin.u16Y,
        stInputPortAttr.stDispWin.u16Width,stInputPortAttr.stDispWin.u16Height);

    STCHECKRESULT(MI_DISP_SetInputPortAttr(DispLayer, u8DispInport, &stInputPortAttr));
    STCHECKRESULT(MI_DISP_EnableInputPort(DispLayer, u8DispInport));
    STCHECKRESULT(MI_DISP_SetInputPortSyncMode(DispLayer, u8DispInport, E_MI_DISP_SYNC_MODE_FREE_RUN));

    /************************************************
    Step5:  bind vpe->disp
*************************************************/
// disp 模块的内容,有几种方式可以使用:
//1、往mi disp buffer填充数据,可有用户自行定义;
//2、可以bind divpdivp输出送给dispdivp的格式和scaler和rotate功能,看客户的需求场景
//3、可以bind到vpe,本例子是直接bind vpeVpe的内容是sensor输入的
    ST_Sys_BindInfo_T stBindInfo;
    memset(&stBindInfo, 0x0, sizeof(ST_Sys_BindInfo_T));
    stBindInfo.stSrcChnPort.eModId = E_MI_MODULE_ID_VPE;
    stBindInfo.stSrcChnPort.u32DevId = 0;
    stBindInfo.stSrcChnPort.u32ChnId = 0;
    stBindInfo.stSrcChnPort.u32PortId = 0;
    stBindInfo.stDstChnPort.eModId = E_MI_MODULE_ID_DISP;
    stBindInfo.stDstChnPort.u32DevId =  0;
    stBindInfo.stDstChnPort.u32ChnId = 0;
    stBindInfo.stDstChnPort.u32PortId = 0;
    stBindInfo.u32SrcFrmrate = SENSOR_RGB_FPS;
    stBindInfo.u32DstFrmrate = SENSOR_RGB_FPS;
    stBindInfo.eBindType = E_MI_SYS_BIND_TYPE_FRAME_BASE;

    STCHECKRESULT(ST_Sys_Bind(&stBindInfo));

    SS_PWM_Config(PANEL_BL_PWM_NUM,pwm_Enable,100,PANEL_BL_PWM_ON);

    return MI_SUCCESS;
}

3.3. 屏启动步骤

3.3.1. 驱动加载

ln -s /customer/misc/config.ini /config/config.ini
insmod /config/modules/4.9.84/mi_panel.ko
insmod /config/modules/4.9.84/mi_disp.ko

加载芯片的panel模块的驱动前,需先ln -s /customer/misc/config.ini /config/config.ini。否则可能会出现无法找到屏参的问题。

3.3.2. 应用启动

启动sdk/verify/mi_demo/source/panel/ st_main_panel.cpp编译出来的应用,就可以点亮屏

Below is an example use of bullet points:

  • {List Bullet 1}

    • {List Bullet 2}

    • {List Bullet 2}

    • {List Bullet 2}

      • {List Bullet 3}

      • {List Bullet 3}

      • {List Bullet 3}

      • {List Bullet 3}