海思Hi3516dv300屏幕调试MIPI TX接口LCD屏幕(京东方JD9366)
一、操作環境
板子:Dopi?Hi3516DV300?開發板 +?京東方JD9366屏幕 +?IMX307攝像頭
電腦:Ubuntu?18.04
SDK版本:?Hi3516CV500_SDK_V2.0.1.1
二、調試簡述?
? ? 一般常見的彩色LCD屏幕的接口模式有:MCU模式,RGB模式,SPI模式,VSYNC模式,DSI模式。第一種模式顧名思義,主要是用于單片機領域,主要的特點就是廉價,以Intel的8080總線協議標準通訊,沒有時鐘以及同步信號,主要由數據總線和控制總線構成,這種LCD驅動IC帶有GRAM,所以顯示的方便率一般比較低,難以做大。與muc屏幕相反,大屏幕一般多采用RGB模式接口,而且此模式除了數據和控制總線以外需要水平和垂直以及時鐘的參與,相比MCU屏幕這個數據更快,一般自己通過LCD外設DMA搬運。SPI模式一般采用較少,有3線和4線的,連線為CS/,SLK,SDI,SDO四根線,連線少但是軟件控制比較復雜。VSYNC模式其實就是就是在MCU模式上加了一個VSYNC信號,應用于運動畫面更新,這樣就與上述兩個接口有很大的區別,該模式支持直接進行動畫顯示的功能,它提供了一個對MCU接口最小的改動,實現動畫顯示的解決方案,在這種模式下,內部的顯示操作與外部VSYNC信號同步,可以實現比內部操作更高的速率的動畫顯示。最后的模式需要更高的CPU頻率支持,常見于現今的智能手機,沒有水平和垂直同步時鐘,控制信號和RGB數據是以報文的形式通過MIPI傳輸的。
? ? 調試DSI的屏幕和CSI接口的攝像頭類似,一般需要一個初始化序列,通過一定的初始化序列后,主控通過MIPI?TX發送RGB數據屏幕才會正常的顯示。
三、調試過程
- 選擇合適的例程
? ? 以sample/vio例子的基礎上進行修改,DOPI開發板直接連接一個攝像頭,通過VI獲取攝像頭數據,VPSS處理,VO輸出顯示至MIPI?TX接口的顯示屏幕上。這個例子的SAMPLE_VIO_ViOnlineVpssOnlineRoute函數已經可以正常在VPSS取攝像頭的流,然后VPSS與VENC和VO進行綁定,為了簡便,將此函數的VENC相關業務邏輯先屏蔽。
/*config vo*/SAMPLE_COMM_VO_GetDefConfig(&stVoConfig);stVoConfig.enDstDynamicRange = enDynamicRange;if (1 == u32VoIntfType){stVoConfig.enVoIntfType = VO_INTF_BT1120;stVoConfig.enIntfSync = VO_OUTPUT_1080P25;}else{stVoConfig.enVoIntfType = VO_INTF_HDMI;}stVoConfig.enPicSize = enPicSize;? ? ?對于DV300,走的是下面,可知默認的輸出是HDMI,我們進行一以下配置。
- 需要開發者修改的
1、將VPSS的輸出配置成與屏幕分辨率一致大小的圖片流,只需在SAMPLE_COMM_VPSS_Start傳入結構體設置便可,顯示屏的分辨率為800*1280,攝像頭是1920*1080,所以先縮小至1280*800,然后再旋轉。
// 設置通道縮放屬性astVpssChnAttr[VpssChn].u32Width = 1280;astVpssChnAttr[VpssChn].u32Height = 800;/*start vpss*/abChnEnable[VpssChn] = HI_TRUE;s32Ret = SAMPLE_COMM_VPSS_Start(VpssGrp, abChnEnable, &stVpssGrpAttr, astVpssChnAttr);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("start vpss group failed. s32Ret: 0x%x !\n", s32Ret);goto EXIT1;}s32Ret = HI_MPI_VPSS_SetChnRotation(VpssGrp, VpssChn, ROTATION_270);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("start HI_MPI_VPSS_SetChnRotation grp %d failed. s32Ret: 0x%x !\n",VpssGrp, s32Ret);return s32Ret;}2、SAMPLE_COMM_VO_GetDefConfig函數添加對應分辨率的參數配置
#ifdef LCD_TYPE_JD9366RECT_S stDefDispRect = {0, 0, 800, 1280};SIZE_S stDefImageSize = {800, 1280};#elseRECT_S stDefDispRect = {0, 0, 1920, 1080};SIZE_S stDefImageSize = {1920, 1080}; #endif...........if(HI3516C_V500 == u32ChipId){pstVoConfig->enVoIntfType = VO_INTF_BT1120;}else{ #ifdef LCD_TYPE_JD9366pstVoConfig->enVoIntfType = VO_INTF_MIPI; #elsepstVoConfig->enVoIntfType = VO_INTF_HDMI; #endif}#ifdef LCD_TYPE_JD9366pstVoConfig->enIntfSync = VO_OUTPUT_USER; #elsepstVoConfig->enIntfSync = VO_OUTPUT_1080P60; #endif修改后,stVoConfig.enVoIntfType為VO_INTF_MIPI類型,stVoConfig.enIntfSync為VO_OUTPUT_USER。
3、SAMPLE_COMM_VO_StartVO修改分辨率大小
4、SAMPLE_COMM_VO_StartVO中將SAMPLE_COMM_VO_StartDev函數換成SetUserIntfSyncInfo_VO_StartDev,具體實現后續說明。
//s32Ret = SAMPLE_COMM_VO_StartDev(VoDev, &stVoPubAttr);s32Ret = SetUserIntfSyncInfo_VO_StartDev(VoDev, &stVoPubAttr);SAMPLE_PRT("SetUserIntfSyncInfo_VO_StartDev s32Ret %x\n",s32Ret);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("SAMPLE_COMM_VO_StartDev failed!\n");return s32Ret;}5、SAMPLE_COMM_VO_StartVO中的SAMPLE_COMM_VO_GetWH會根據stVoConfig.enIntfSync獲取分辨率以及幀率信息,根據自己屏幕的參數進行修改。
case VO_OUTPUT_USER : #ifdef LCD_TYPE_JD9366*pu32W = 800;*pu32H = 1280;*pu32Frm = 60; #else*pu32W = 720;*pu32H = 576;*pu32Frm = 25; #endifbreak;6、根據LCD驅動IC需要的時序對時序參數結構體進行配置,通過海思的文檔進行輸入,然后對應參數會自動計算出來。根據ReleaseDoc\zh\02.only for reference\software下的《RGB_MIPI屏幕時鐘時序計算器.xlsx》進行設置。
注意的是下面切換到MIPI屏適配VDP時鐘時序。
?
相關的時序信息綠色輸入,相關配置紅色輸出。在SAMPLE_COMM_VO_StartVO函數實現的.c文件里面添加一個機構體:
combo_dev_cfg_t MIPI_TX_800X1280_USER_CONFIG = {.devno = 0,.lane_id = {0, 1, 2, 3},.output_mode = OUTPUT_MODE_DSI_VIDEO,.output_format = OUT_FORMAT_RGB_24_BIT,.video_mode = BURST_MODE,.sync_info = {.vid_pkt_size = 800, // hact.vid_hsa_pixels = 4, // hsa.vid_hbp_pixels = 40, // hbp.vid_hline_pixels = 884, // hact + hsa + hbp + hfp.vid_vsa_lines = 2, // vsa.vid_vbp_lines = 22, // vbp.vid_vfp_lines = 16, // vfp.vid_active_lines = 1320, //vact.edpi_cmd_size = 0,},.phy_data_rate = 421,.pixel_clk = 70013,};相關參數信息有計算的得到的紅色數據獲取?,里面還說明了TX?Lane的使用數量以及ID、數據格式和輸出模式。
7、根據剩下的參數實現SetUserIntfSyncInfo_VO_StartDev函數。
HI_S32 SetUserIntfSyncInfo_VO_StartDev(VO_DEV VoDev, VO_PUB_ATTR_S* pstPubAttr) {HI_S32 s32Ret = HI_SUCCESS;HI_U32 u32Framerate = 60;VO_USER_INTFSYNC_INFO_S stUserInfo = {0};/* Fill pub attr */pstPubAttr->enIntfType = VO_INTF_MIPI;pstPubAttr->enIntfSync = VO_OUTPUT_USER;pstPubAttr->stSyncInfo.bSynm = 0; pstPubAttr->stSyncInfo.bIop = 1; pstPubAttr->stSyncInfo.u8Intfb = 0; pstPubAttr->stSyncInfo.u16Vact = 1280; pstPubAttr->stSyncInfo.u16Vbb = 24; pstPubAttr->stSyncInfo.u16Vfb = 16; pstPubAttr->stSyncInfo.u16Hact = 800; pstPubAttr->stSyncInfo.u16Hbb = 44;pstPubAttr->stSyncInfo.u16Hfb = 40;pstPubAttr->stSyncInfo.u16Hmid = 1; pstPubAttr->stSyncInfo.u16Bvact = 1; pstPubAttr->stSyncInfo.u16Bvbb = 1; pstPubAttr->stSyncInfo.u16Bvfb = 1; pstPubAttr->stSyncInfo.u16Hpw = 4; pstPubAttr->stSyncInfo.u16Vpw = 2; pstPubAttr->stSyncInfo.bIdv = 0; pstPubAttr->stSyncInfo.bIhs = 0; pstPubAttr->stSyncInfo.bIvs = 0; s32Ret = HI_MPI_VO_SetPubAttr(VoDev, pstPubAttr);if (s32Ret != HI_SUCCESS){SAMPLE_PRT("failed with %#x!\n", s32Ret);return HI_FAILURE;}/* Fill user sync info */stUserInfo.stUserIntfSyncAttr.enClkSource = VO_CLK_SOURCE_PLL;stUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Fbdiv = 70;//PLL整數倍頻系數 0-0xfffstUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Frac= 0x346DC;stUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Refdiv = 2;stUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Postdiv1 = 4;stUserInfo.stUserIntfSyncAttr.stUserSyncPll.u32Postdiv2 = 3;stUserInfo.u32DevDiv = 1;stUserInfo.u32PreDiv = 1;/* Set user interface sync info */s32Ret = HI_MPI_VO_SetUserIntfSyncInfo(VoDev, &stUserInfo);if (s32Ret != HI_SUCCESS){printf("Set user interface sync info failed with %x.\n",s32Ret);return HI_FAILURE;}s32Ret = HI_MPI_VO_SetDevFrameRate(VoDev, u32Framerate);s32Ret = HI_MPI_VO_Enable(VoDev);if (s32Ret != HI_SUCCESS){SAMPLE_PRT("failed with %#x!\n", s32Ret);return HI_FAILURE;}return s32Ret; }?8、SAMPLE_COMM_VO_StartVO最后面調用了SAMPLE_COMM_VO_StartMipiTx函數,對此函數進行修改
case VO_OUTPUT_USER:pstMipiTxConfig = &MIPI_TX_800X1280_USER_CONFIG;break;?9、添加初始化序列,在SAMPLE_COMM_VO_StartVO最后面調用了SAMPLE_COMM_VO_StartMipiTx函數中調用了SAMPLE_PRIVATE_VO_InitMipiTxScreen對MIPI屏幕進行初始化。相關細節見下。
- 海思平臺MIPI?TX如何發送初始化序列
在文檔:ReleaseDoc\zh\02.only for reference\software《屏幕對接 使用指南.pdf》中有說到MIPI?TX三種模式配置方式,根據給的初始化列表選擇合適的方式。拿JD9366屏幕初始化給的是往8Bit的寄存器地址里面寫一個8Bit的數據,假設往0x11地址里面寫0x22操作的方法是:
cmd_info.devno = 0;cmd_info.cmd_size = 0x2211; // H:data L:regcmd_info.data_type = 0x15;cmd_info.cmd = NULL;s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("MIPI_TX SET CMD failed\n");close(fd);return -1;}假設就發送一個命令0x29:
cmd_info.devno = 0;cmd_info.cmd_size = 0x0029;cmd_info.data_type = 0x23;cmd_info.cmd = NULL;s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("MIPI_TX SET CMD failed\n");close(fd);return;}有的LCD需要一定的上電時序以及需要硬件復位,在初始化函數里面拉下IO對LCD硬件復位。?
四、調試問題
1、不出圖
不出圖的原因有很多,可以參考《屏幕對接 使用指南.pdf》中顯示colorbar,先用示波器看MIPI?Lane有無數據輸出以判斷初始化是否正常,MIPI Lane的協議相對復雜,以本人的經驗一般來說當看見MIPI?Lane有一定規律波形輸出可以近似看成刷的初始化序列是正常的,首先查看芯片端配置的時序是否合適,對時序進行修改下;從開始到顯示逐步排查每個環節的問題以定位。如果直接Lane沒有數據,查看電壓、Reset等有效電壓。時序參數不正常會出現一些色彩差等原因。
2、視頻層正常但是UI層顏色不正常,UI層默認是RGB顯示,所以要設置UI通道不要YUV轉化顯示,在VO初始化前加:
VO_CSC_S pstCSC;HI_MPI_VO_GetGraphicLayerCSC(0, &pstCSC);pstCSC.enCscMatrix = VO_CSC_MATRIX_IDENTITY;HI_MPI_VO_SetGraphicLayerCSC(0, &pstCSC);?
五、結語
源碼與文檔:戳這里
Dopi?開發板交流群:735884031
總結
以上是生活随笔為你收集整理的海思Hi3516dv300屏幕调试MIPI TX接口LCD屏幕(京东方JD9366)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 区块链骗局的改善
- 下一篇: 浅浅总结一下HTML吧