Panel开发参考
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. 屏参配置文件介绍¶
-
给新的屏参定义一个section name,可以随意定义但是不能和现有section name相同
-
将新的屏参section name追加到ROOT section中的m_pnlList变量中(不同接口的LCD section只能存在一个,比如m_pnlList中已经存在一个TTL的panel section name,那么如果想要添加新的TTL,只能删除掉之前存在的section)
-
将新的屏参参数添加到新的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 到divp,divp输出送给disp;divp的格式和scaler和rotate功能,看客户的需求场景 //3、可以bind到vpe,本例子是直接bind vpe。Vpe的内容是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}
-
-