> 文章列表 > 16_I.MX6ULL_eLCDIF接口

16_I.MX6ULL_eLCDIF接口

16_I.MX6ULL_eLCDIF接口

目录

eLCDIF接口

相关寄存器 

配置步骤

LCD像素时钟的设置


eLCDIF接口

LCDIF是I.MX6U自带的液晶屏幕接口,用于连接RGB LCD接口的屏幕,eLCDIF接口特性如下:

1.支持RGB LCD的DE模式。

2.支持VSYNC模式以实现高速数据传输。

3.支持ITU-R BT.656格式的4:2:2的YCbCr 数字视频,并且将其转换为模拟TV信号。

4.支持8/16/18/24/32位LCD。

eLCDIF支持三种接口:MPU 接口、VSYNC 接口和DOTCLK接口,这三种接口区别如下:

1.MPU 接口

MPU接口用于在I.MX6U和LCD屏幕直接传输数据和命令,这个接口用于6080/8080接口的LCD屏幕,比如我们学习STM32的时候常用到的MCU屏幕。如果寄存器LCDIF_CTRL的位 DOTCLK_MODE、DVI_MODE和VSYNC_MODE都为0的话就表示LCDIF工作MPU接口模式。

2.VSYNC接口VSYNC接口时序和MPU接口时序基本一样,只是多了VSYNC 信号来作为帧同步,当LCDIF_CTRL 的位VSYNC_MODE为1的时候此接口使能。

3.DOTCLK 接口

DOTCLK接口就是用来连接RGBLCD接口屏幕的,它包括VSYNC、HSYNC、DOTCLK和ENABLE(可选的)这四个信号,这样的接口通常被称为RGB接口。DOTCLK接口时序如图所示:

相关寄存器 

LCDIF_CTRL寄存器,此寄存器结构如图所示:

 

SFTRST(bit31): eLCDIF软复位控制位,当此位为1的话就会强制复位LCD

CLKGATE(bit30):正常运行模式下,此位必须为0!如果此位为1的话时钟就不会进入到LCDIF。

BYPASS_COUNT(bit19):如果要工作在DOTCLK模式的话就此位必须为1。

VSYNC_MODE(bit18):此位为1的话LCDIF工作在VSYNC 接口模式。

DOTCLK_MODE(bit17):此位为1的话LCDIF工作在DOTCLK接口模式。

INPUT_DATA_SWIZZLE(bit15:14):输入数据字节交换设置,此位为0的话不交换字节也就是小端模式:为1的话交换所有字节,也就是大端模式:为2的话半字交换;为3 的话在每个半字内进行字节交换。

CSC-DATA-SWIZZLE(bit13:12) : CSC数据字节交换设置,交换方式和INPUT_DATA_SWIZZLE一样。

LCD_DATABUS_WIDTH(bit11:10): LCD数据总线宽度,为0的话总线宽度为16位;为1的话总线宽度为8位;为2的话总线宽度为18位;为3的话总线宽度为24 位。

WORD-LENGTH(bit9:8):输入的数据格式,也就是像素数据宽度,为0的话每个像素16位;为 1 的话每个像素8位;为2的话每个像素18位;为3的话每个像素24位。

MASTER(bit5):为1的话设置eLCDIF工作在主模式。

DATA_FORMAT_16_BIT(bit3):当此位为1并且WORD_LENGTH为0的时候像素格式为ARGB555,当此位为0并且WORD LENGTH为0的时候像素格式为RGB565。

DATA_FORMAT_18_BIT(bit2):只有当WORD_LENGTH为2的时候此位才有效,此位为0的话低18位有效,像素格式为RGB666,高14位数据无效。当此位为1的话高18位有效,像素格式依旧是RGB666,但是低14位数据无效。

DATA-FORMAT-24-BIT(bit1):只有当wORD-LENGTH为3的时候此位才有效,为0的时候表示全部的24位数据都有效。为1的话实际输入的数据有效位只有18位,虽然输入的是24位数据,但是每个颜色通道的高2位数据会被丢弃掉。

RUN(bit0): eLCDIF接口运行控制位,当此位为1的话eLCDIF接口就开始传输数据,也就是 eLCDIF的使能位。

寄存器LCDIF CTRL1

BYTE_PACKING_FORMAT(bit19:16),此位用来决定在32位的数据中哪些字节的数据有效,默认值为0xF,也就是所有的字节有效,当为0的话表示所有的字节都无效。如果显示的数据是24位(ARGB格式,但是A通道不传输)的话就设置此位为0x7

寄存器LCDIF_TRANSFER_COUNT,这个寄存器用来设置所连接的RGBLCD 屏幕分辨率大小,此寄存器结构如图所示:

 寄存器LCDIF_TRANSFER_COUNT分为两部分,高16位和低16位,高16位是V_COUNT,是LCD的垂直分辨率。低16位是H_COUNT,是LCD的水平分辨率。如果LCD分辨率为1024*600的话,那么V_COUNT就是600, H_COUNT就是1024。

寄存器LCDIF_VDCTRL0,这个寄存器是 VSYNC和DOTCLK模式控制寄存器0,寄存器结构如图所示:

 

VSYNC_OEB(bit29): VSYN 信号方向控制位,为0的话VSYNC是输出,为1的话VSYNC 是输入。

ENABLE_PRESENT(bit28): EBABLE数据线使能位,也就是DE数据线。为1的话使能ENABLE 数据线,为0的话关闭ENABLE数据线。

VSYNC_POL(bit27):VSYNC数据线极性设置位,为0的话VSYNC低电平有效,为1的话VSYNC 高电平有效,要根据所使用的 LCD数据手册来设置。

HSYNC_POL(bit26):HSYNC数据线极性设置位,为0的话HSYNC低电平有效,为1的话HSYNC高电平有效,要根据所使用的LCD数据手册来设置。

DOTCLK_POL(bit25): DOTCLK数据线(像素时钟线 CLK)极性设置位,为0的话下降沿锁存数据,上升沿捕获数据,为1的话相反,要根据所使用的LCD数据手册来设置。

ENABLE_POL(bit24):EANBLE数据线极性设置位,为0的话低电平有效,为1的话高电平有效。

VSYNC_PERIOD_UNIT(bit21): VSYNC信号周期单位,为0的话VSYNC周期单位为像素时钟。为1的话VSYNC周期单位是水平行,如果使用DOTCLK模式话就要设置为1。

VSYNC-PULSE_WIDTH_UNIT(bit20):VSYNC信号脉冲宽度单位,和VSYNC_PERIOD_UNUT一样,如果使用DOTCLK模式的话要设置为1。

VSYNC-PULSE-WIDTH(bit17:0): VSPW参数设置位。

寄存器LCDIF_VDCTRL1,这个寄存器是VSYNC和DOTCLK模式控制寄存器1,此寄存器只有一个功能,用来设置VSYNC总周期,就是:屏幕高度+VSPW+VBP+VFP。

寄存器LCDIF_VDCTRL2,这个寄存器分为高16位和低16位两部分,高16位是

HSYNC_PULSE-WIDTH,用来设置HSYNC信号宽度,也就是HSPW。低16位是HSYNC PERIOD,设置HSYNC总周期,就是:屏幕宽度+HSPW+HBP+HFP。

 

HORIZONTAL_WAIT_CNT(bit27:16):此位用于 DOTCLK 模式,用于设置HSYNC信号产生到有效数据产生之间的时间,也就是HSPW+HBP。

寄存器 LCDIF_VDCTRL3,此寄存器结构如图 24.1.2.4所示: 

VERTICAL_WAIR_CNT(bit15:0):和HORIZONTAL_WAIT_CNT 一样,只是此位用于VSYNC 信号,也就是 VSPW+VBP。

HORIZONTAL_WAIT_CNT(bit27:16):此位用于 DOTCLK 模式,用于设置HSYNC信号产生到有效数据产生之间的时间,也就是HSPW+HBP。

VERTICAL_WAIR_CNT(bit15:0):和HORIZONTAL_WAIT_CNT 一样,只是此位用于VSYNC 信号,也就是 VSPW+VBP。

寄存器LCDIF_VDCTRL4,此寄存器结构如图所示:

 

SYNC_SIGNALS_ON(bit18):同步信号使能位,设置为1的话使能VSYNC、HSYNC、DOTCLK 这些信号。

DOTCLK_H_VALID_DATA_CNT(bit15:0):设置LCD的宽度,也就是水平像素数量。

最后在看一下寄存器LCDIF_CUR_BUF和LCDIF_NEXT_BUF,这两个寄存器分别为当前帧和下一帧缓冲区,也就是LCD显存。一般这两个寄存器保存同一个地址,也就是划分给LCD的显存首地址。

配置步骤

使用I.MX6U的eLCDIF接口来驱动ALIENTEK的ATK7016这款屏幕,配置步骤如下:

1.初始化LCD所使用的IO

首先肯定是初始化LCD所示使用的IO,将其复用为eLCDIF接口IO。

2.设置LCD的像素时钟

查阅所使用的LCD屏幕数据手册,或者自己计算出的时钟像素,然后设置CCM相应的寄存器。

3.配置eLCDIF 接口

设置LCDIF的寄存器CTRL、CTRL1、TRANSFER_COUNT、VDCTRLO-4、CUR_BUF和NEXT_BUF。根据 LCD 的数据手册设置相应的参数。

4.编写API函数

驱动LCD屏幕的目的就是显示内容,所以需要编写一些基本的API函数,比如画点、画线、画圆函数,字符串显示函数等。

LCD像素时钟的设置

LCD需要一个CLK信号,这个时钟信号是6ULL的CLK引脚发送给RGB LCD的。

像素时钟就是RGBLCD的时钟信号,以ATK7016这款屏幕为例,显示一帧图像所需要的时钟数就是:

=(VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP)

=(3+20+600 +12)* (20+140+ 1024+160)

=635 * 1344

=853440

显示一帧图像需要853440个时钟数,那么显示60帧就是:853440*60=51206400~51.2M,所以像素时钟就是51.2MHz。

1.此部分是一个选择器,用于选择哪个PLL可以作为LCDIF 时钟源,由寄存器CCM-CSCDR2的位LCDIF1-PRE-CLK-SEL(bit17:15)来决定, LCDIF1-PRE-CLK-SEL选择设置如表所示:

 

2.此部分是LCDIF时钟的预分频器,由寄存器CCM_CSCDR2的位LCDIF1_PRED来决定预分频值。可设置值为0-7,分别对应1-8分频。

3.此部分进一步分频,由寄存器CBCMR的位LCDIF1_PODF来决定分频值。可设置值为0-7,分别对应1-8分频。

4.此部分是一个选择器,选择LCDIF最终的根时钟,由寄存器CSCDR2的位LCDIF1_CLK_SEL决定,LCDIF1_CLK_SEL选择设置如所示:

 

这里肯定选择PLL5出来的那一路时钟作为LCDIF的根时钟,因此LCDIF1_CLK_SEL设置为0。 LCDIF既然选择了PLL5作为时钟源,那么还需要初始化PLL5, LCDIF的时钟是由PLLS 和图 中的1、2这两个分频值决定的,所以需要对这三个进行合理的设置以搭配出所需的时钟值,我们就以ATK7016屏幕所需的51.2MHz为例,看看如何进行配置。

PLL5频率设置涉及到四个寄存器:CCM_PLL_VIDEO、CCM_PLL_VIDEO-NUM、

CCM_PLL_VIDEO_DENOM、CCM_MISC2 。

其中CCM_PLL_VIDEO_NUM和CCM_PLL_VIDEO_DENOM这两个寄存器是用于小数分频的,我们这里为了简单不使用小数分频,因此这两个寄存器设置为0。

PLL5的时钟计算公式如下:

PLL5_CLK = OSC24M * (loopDivider + (denominator / numerator)) / postDivider

不使用小数分频的话PLL5时钟计算公式就可以简化为:

PLL5_CLK = OSC24M * loopDivider / postDivider

OSC24M就是24MHz的有源晶振,现在的问题就是设置loopDivider和postDivider。先来看一下寄存器CCM_PLL_VIDEO,此寄存器结构如图所示:

 

POST_DIV_SLECT(bit20:19):此位和寄存器CCM_ANALOG_CCMSC2的VIDEO_DIV位共同决定了postDivider,为0的话是4分频,为1的话是2分频,为2的话是1分频。

ENABLE(bit13): PLL5(PLL_VIDEO)使能位,为1的话使能PLL5,为0的话关闭PLL5。

DIV SELECT(bit6:0): loopDivider值,范围为27-54,。

寄存器CCM_ANALOG_MISC2的位VIDEO_DIV(bit31:30)与寄存器CCM_PLL_VIDEO的位POST_DIV_SLECT(bit20:19)共同决定了postDivider,通过这两个的配合可以获得2、4、8、16 分频。本章将VIDEO_DIV设置为 0,也就是1分频,因此postDivider就是1, loopDivider设置为32, PLL5的时钟频率就是:

PLLS_CLK=OSC24M * loopDivider / postDivider

=24M *32/1

=768MHz。

PLL5此时为768MHz,在经过图中的②和③进一步分频,设置②中为3分频,也就是寄存器CCM_CSCDR2的位LCDIF1_PRED(bit14:12)为2。设置3中为5分频,就是寄存器CCM_CBCMR的位LCDIF1_PODF(bit25:23)为4。

设置好以后最终进入到LCDIF的时钟频率就是: 768/3/5=51.2MHz,这就是我们需要的像素时钟频率。