3.3. 使用说明

3.3.1. 连接开发板

AiPQ 工具使用需要先连接开发板。

  1. 打开 连接板子 connect_tab 标签页

  2. 选择板子型号和连接类型

  3. 点击连接

AiPQ 支持两种连接方式:

  • 串口

  • USB ADB

注解

  • MIPI-DSI 屏幕调试依赖 ADB, ADB 连接成功后显示 MIPI-DSI 调试页面

../../_images/connect.gif

3.3.2. 调屏

系统启动后,可以在调屏标签页 panel_debug_tab 调试 LCD 屏幕的显示效果。

3.3.2.1. 调屏步骤

1.连接开发板: 详见 连接开发板 章节

2.读取配置: AiPQ 工具读取开发板当前 LCD 配置,详见 读取配置 章节

3.颜色测试: 简单测试当前 LCD 显示效果,详见 颜色测试 章节,如果 LCD 显示明显异常,此步骤可跳过

4.修改配置: 根据颜色测试结果或当前 LCD 显示效果修改相关的参数配置,详见 修改配置 章节

5.写入配置: 将修改后的参数写入到开发板上,并重启 LCD 屏幕使新参数生效。详见 写入配置 章节

6.导出配置:导出屏幕相关的 DTS 配置,MIPI-DSI 接口同时导出初始化代码

7.将新配置复制到 board.dts 或者屏驱动源码中,重新编译烧录

3.3.2.2. 读取配置

选择显示接口,点击右下方 读取配置 read_bottom 按键,AiPQ 工具自动获取当前 LCD 配置。

../../_images/disp_interface.gif

当前 AiPQ 工具支持 RGB , LVDS , MIPI-DSI 等显示接口。

../../_images/read.gif

3.3.2.3. 颜色测试

颜色测试可简单判断 LCD 屏幕是否成功点亮并且检验显示是否正常。在颜色测试中,SoC 不再从 DDR 或 PSRAM 中读取数据,而是直接生成特定的颜色图像,然后传输给 LCD 屏幕显示。

测试步骤

  1. 点击 颜色测试 color_test 按键

  2. 选择测试模式

  3. 使能颜色测试

  4. 点击 开始测试

测试模式

  • color bar: 彩色条纹模式

../../_images/color_test.gif

正常的 color bar 效果如下所示,8 种不同颜色的竖条均匀地重复分布:

../../_images/colorbar.png

3.3.2.4. 修改配置

根据 LCD 实际的显示效果,修改对应的参数配置。

  • 背光不亮
    • 控制相关 GPIO 引脚,包括 backlight, power 等

  • 屏幕闪烁

    • 调整时序参数,增加 pixelclk ,提高帧率

  • 图像显示错位

    • 调整水平和垂直消隐区参数,根据显示效果增大/减小消隐区,找到最佳显示效果

  • RGB 屏幕颜色有误

    • 调整 RGB 输出顺序

    • 修改 RGB format

    • 检查 pinmux 选项

  • LVDS 屏幕颜色有误

    • 显示白屏,调整 CK 通道顺序

    • 对比原理图,调整 D0 - D3 数据通道的极性和顺序

    • 图像列像素出现互换,使能 link swap

  • MIPI-DSI 屏幕无输出

    • reset 引脚输出有效电平

    • 对比原理图,调整数据通道的极性和输出顺序

    • 对比原理图,调整时钟通道的极性

    • 核对初始化 command 是否正确

    • 输入屏幕自检命令,检测主控与屏幕通信是否正常

更多调试思路可以参考 SDK 使用指南,Display 使用指南中的调屏常见问题。

3.3.2.4.1. 时序参数

timing 参数列表如下:

../../_images/timing.png

pixelclk 单位为 MHz, 其计算公式为:

pixelclk = (hactive + hfp + hbp + hsync) * (vactive + vfp + vbp + vsync) * fps

点击 写入配置 write_bottom 按钮使新参数生效,AiPQ 工具会自动计算帧率 (fps)。

参数说明

timing 参数列表对应 board.dts 中 panel 节点的 display-timings 子节点或屏驱动源码中的 struct videomode 结构体

// board.dts
panel_xxx {
...
    display-timings {
        native-mode = <&timing0>;
        timing0: 1024x600 {
            clock-frequency = <52000000>;   // pixelclk
            hactive = <1024>;
            vactive = <600>;
            hback-porch = <160>;
            hfront-porch = <160>;
            hsync-len = <20>;
            vback-porch = <12>;
            vfront-porch = <20>;
            vsync-len = <3>;
            de-active = <1>;
            pixelclk-active = <1>;
        };
    };
};

屏驱动源码 panel_xxx.c

/* Init the videomode parameter, dts will override the initial value. */
static struct videomode panel_vm = {
    .pixelclock = 130000000,
    .hactive = 1080,
    .hfront_porch = 160,
    .hback_porch = 160,
    .hsync_len = 40,
    .vactive = 1920,
    .vfront_porch = 10,
    .vback_porch = 20,
    .vsync_len = 8,
    .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
        DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE
};

3.3.2.4.2. RGB

../../_images/rgb.png

RGB 所有参数都集中在 board.dstpanel_rgb 节点。

panel_rgb {
    ...
    rgb-mode = <PRGB>;
    interface-format = <PRGB_16BIT_LD>;
    clock-phase = <DEGREE_0>;
    data-order = <RGB>;
    data-mirror;
    ...
};
  • mode

    RGB 模式,当前 AiPQ 工具仅支持并行 RGB 模式,对应的节点属性:

rgb-mode = <PRGB>;
  • format

    RGB 显示接口的输出格式,对应的节点属性:

interface-format = <PRGB_16BIT_LD>;

format

interface-format

备注

24BIT

PRGB_24BIT

RGB888 24 个数据 pin 输出

18BIT_LD

PRGB_16BIT_LD

Lowest Discarded, 将 24 个 pin 中最低 6 个 pin 丢弃

18BIT_HD

PRGB_16BIT_LD

Highest Discarded, 将 24 个 pin 中最高 6 个 pin 丢弃

16BIT_LD

PRGB_16BIT_LD

Lowest Discarded, 将 24 个 pin 中最低 8 个 pin 丢弃

16BIT_HD

PRGB_16BIT_LD

Highest Discarded, 将 24 个 pin 中最高 6 个 pin 丢弃

PRGB 的 18bit/16bit 提供 2 种输出模式,可根据不同的封装或走线需求进行选择。

pin 脚使用详情可通过 pinmux 配置 页面查看。

  • clock-phase

    pixel时钟输出相位选择, 允许时钟上升沿延后数据 0°/90°/180°/270° 相位,对应的节点属性:

clock-phase = <DEGREE_0>;

clock phase

dts

备注

0

DEGREE_0

时钟上升沿延后数据 0° 相位

90

DEGREE_90

时钟上升沿延后数据 90° 相位

180

DEGREE_180

时钟上升沿延后数据 180° 相位

270

DEGREE_270

时钟上升沿延后数据 270° 相位

  • data-order

    RGB 数据的输出顺序,R/G/B 三组信号可按任意顺序输出,对应的节点属性:

data-order = <RGB>;

data-order

dts

备注

RGB

RGB

AiPQ 工具选项与 dts 配置同名

RBG

RBG

BGR

BGR

BRG

BRG

GRB

GRB

GBR

GBR

  • data-mirror

    RGB 数据组内大小端输出。默认输出低位到高位 0 - 7,使能则变为 7 - 0 输出,对应的节点属性:

data-mirror;

data-mirror 是布尔型参数,如果想 disable data-mirror,删除该属性即可。

pinmux 配置

ArtInChip SoC 产品接口丰富,pinmux 配置页面能为 RGB 屏幕的 pin 脚连接提供参考,帮助工程师更高效地阅读开发板原理图。

此外,pinmux 配置页面允许 enable/disable 引脚的 lcd 数据输出,支持简单的 lcd pin 调试。

pinmux 配置对应 rgb0 节点的 pinctrl-0 属性:

&rgb0 {
      pinctrl-names = "default", "sleep";
      pinctrl-0 = <&lcd_rgb565_ld_pins>;
      pinctrl-1 = <&lcd_rgb565_ld_sleep_pins>;
}

pinctrl-0 对应 default 配置,用于屏幕正常显示, sleeep 配置用于屏幕休眠。

pinmux

pinctrl-0

备注

24

lcd_pins

QFN88

24

lcd1_pins

QFN88128

18_LD

lcd_rgb666_ld_pins

18_HD

lcd_rgb666_hd_pins

16_LD

lcd_rgb565_ld_pins

16_HD

lcd_rgb565_hd_pins

../../_images/rgb_pinmux.gif

小技巧

部分 RGB888 屏幕在实际使用上呈现 RGB666 的效果,可通过禁用 RGB 三组 pin 脚的低位进行测试。

3.3.2.4.3. LVDS

../../_images/lvds.png

LVDS 参数涉及 board.dts 里两个节点,panel_lvdslvds0

  • panel_lvds 节点配置: mode, link-mode

  • lvds0 节点配置: link swap, lines, N/P swap

panel_lvds {
    ...
    data-mapping = "vesa-24";
    data-channel = "single-link1";
    ...
};

&lvds0 {
    ...
    link-swap = <1>;
    lines = <0x43210>;
    pols = <0x1>;
    ...
};

各参数说明

  • mode

    LVDS 模式设置,支持 vesa-24, jeida-24, jeida-18 等接口标准,对应的节点属性为:

panel_lvds {
    ...
    data-mapping = "vesa-24";
    ...
};

LVDS Mode

data-mapping

备注

VESA-24(NS)

vesa-24

String 类型参数

JEIDA-24

jeida-24

String 类型参数

JEIDA-18

jeida-18

String 类型参数

  • link-mode

    LVDS Link 模式设置,对应的节点属性为:

panel_lvds {
    ...
    data-channel = "single-link1";
    ...
};

LVDS Link mode

data-channel

备注

SINGLE_LINK0

single-link0

单link输出,输出选择 link0 通道

SINGLE_LINK1

single-link0

单link输出,输出选择 link1 通道

DOUBLE_SCREEN

double-screen

单link输出,link0 和 link1 同时输出,可驱动双屏同显

DUAL_LINK

dual-link

dual link输出,奇偶像素同时输出

  • link swap

    LVDS Link0 与 Link1 整组交换。使能 Link swap 后,Link1 的 pin 脚输出 Link0 的数据,Link0 的 pin 脚输出 link1 的数据。对应的节点属性为:

&lvds0 {
    ...
    link-swap = <1>;
    ...
};
  • lines

    控制 LVDS Link 内部 5 个通道的差分信号输出,允许 5 对差分信号任意互换。对应的节点属性为:

    5 对差分信号分别为 D3 CK D2 D1 D0,缺省值为:0x43210,每个 byte 表示一个差分信号。

配置例程:

  1. 0x43210 表示从左到右,第一个通道输出 D3,第二个通道输出 CK,第三个通道输出 D2,第四个通道输出 D1,第五个通道输出 D0

  2. 0x01234 表示从左到右,第一个通道输出 D0,第二个通道输出 D1,第三个通道输出 D2,第四个通道输出 CK,第五个通道输出 D3

&lvds0 {
    ...
    lines = <0x43210>;
    ...
};
  • N/P swap

    LVDS Link 差分信号的极性控制,默认正相。 低 5 bit 分别控制 LVDS 五个通道差分信号的极性。对应的节点属性为:

&lvds0 {
    ...
    pols = <0x3>;
    ...
};

配置例程:

  1. 0x3 表示第四个和第五个通道反相。

  2. 0x8 表示第二个通道反相。

3.3.2.4.4. MIPI-DSI

../../_images/mipi_dsi.png

MIPI-DSI 接口参数涉及屏驱动源码和 board.dts

  • mode

    dsi 模式设置,对应屏驱动源码的 struct panel_dsi 结构体。

static struct panel_dsi = {
    .mode = DSI_MOD_VID_BURST,
};

dsi mode

panel_dsi

备注

VID_PULSE

DSI_MOD_VID_PULSE

video pulse mode

VID_EVENT

DSI_MOD_VID_EVENT

video event mode

VID_BURST

DSI_MOD_VID_BURST

video burst mode

CMD_MODE

DSI_MOD_CMD_MODE

command mode

  • format

    dsi 显示接口输出格式,对应屏驱动源码的 struct panel_dsi 结构体。

static struct panel_dsi = {
    .format = DSI_FMT_RGB888,
};

dsi format

panel_dsi

备注

RGB888

DSI_FMT_RGB888

rgb888

RGB666L

DSI_FMT_RGB666l

rgb666 packed

RGB666

DSI_FMT_RGB666

rgb666

RGB565

DSI_FMT_RGB565

rgb565

  • lane_num

    数据通路数量,支持 1 ~ 4 组差分数据通路,对应屏驱动源码的 struct panel_dsi 结构体。

static struct panel_dsi = {
    .lane_num = 4,
};
  • data lanes

    数据通道输出控制,允许数据通道任意互换,时钟通道不支持交换。对应 board.dts 属性:

&dsi0 {
    ...
    data-lanes = <0 1 2 3>;
    ...
};

注解

AiPQ 工具数据通道排布,从左往右,从数据通道3 依次递减到数据通道 0,与 board.dts 中的 data-lanes 属性相反。

配置例程:

  1. data-lanes = <0 1 2 3> 表示数据通道0 输出 D0,数据通道1 输出 D1,以此类推

  2. data-lanes = <3 2 1 0> 表示数据通道0 输出 D3,数据通道1 输出 D2,以此类推

  • N/P swap

    dsi 数据通路极性控制,默认正相。0 表示当前通道极性正相,1 表示当前通道极性反相。与 data-lanes 配置的通道顺序保持一致。对应 board.dts 属性:

&dsi0 {
    ...
    lanes-polarities = <0 0 0 0>;
    ...
};
  • clk inverse

    dsi 时钟通路极性控制,默认正相。对应 board.dts 属性如下,配置后时钟通路极性反相。

&dsi0 {
    ...
    data-clk-inverse;
    ...
};

data-clk-inverse 是布尔型参数,如果时钟通路极性为正相,需要删除该属性。

  • VC

    dsi 虚拟通道 ID,Virtual Channel Identifier。对应 board.dts 属性:

panel_dsi {
    ...
    reg = <0>;
    ...
};

MIPI-DSI command

AiPQ 工具支持添加 MIPI-DSI 屏幕的初始化 command,允许从 txt 文件导入,或者直接在 mipi 命令窗口编辑。

../../_images/mipi_dsi_command.gif

command 语法:

header data

命令以行为单位,每行以特定的标志开头,允许空行,不支持数据换行,数据标志头如下:

  • mipi.dcs

  • mipi.generic

  • delay

delay 以毫秒为单位进行延时。

mipi.generic    0xF0,0xC3
mipi.generic    0xE4,0x40,0x0F,0x2F
mipi.dcs    0x11
delay       120
mipi.dcs    0x29

3.3.2.4.5. GPIO

调屏功能支持控制 GPIO 引脚,用于测试 LCD 外设的 backlight, reset, power 等引脚。

../../_images/gpio.gif

在 GPIO 命令编辑窗口写入 GPIO 操作指令,点击 写入配置 使 GPIO 操作生效。

GPIO 操作指令格式:

  • PXn

    P: 标记头,X: GPIO 组编号,n: GPIO 组内编号。例如: PF19 表示 F 组第 19 引脚。

  • delay

    以毫秒为单位进行延时

  • 0/1

    0/1 指定输出高低电平

小技巧

  • GPIO 操作为最高优先级,指定的引脚会强制设为通用 GPIO,并输出指定电平。

  • GPIO 需要添加到 board.dtspanel_xxx 节点,在屏驱动源码中自行读取并设置高低电平。GPIO 操作窗口仅供调试。

3.3.2.5. 写入配置

参数修改完成后,点击 写入配置 write_bottom 按钮。 AiPQ 工具会重启 LCD 屏幕并让新参数生效。

../../_images/write_timing.gif

3.3.2.6. 导出配置

LCD 调试完成后,点击 导出配置 aipq_export_bottom 按钮,导出相关配置。

  • RGB/LVDS 接口 导出 DTS 配置

  • MIPI-DSI 导出 DTS 配置和初始化代码。

../../_images/aipq_export_dts.gif

MIPI-DSI 初始化代码会导出一个 panel_enable() 函数,将其复制替换 MIPI-DSI simple panel 源码的同名函数。 simple panel 源码地址:

  • Kernel 源码地址: source/linux-5.10/drivers/video/artinchip/disp/panel/

  • Uboot 源码地址: source/uboot-2021.10/drivers/video/artinchip/display/panel/

以 MIPI-DSI 接口为例,导出的参数如下所示:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
panel_dsi {
	compatible = "artinchip,aic-dsi-panel-simple";
	status = "okay";
	u-boot,dm-pre-reloc;

	enable-gpios = <&gpio_e 19 GPIO_ACTIVE_HIGH>;

	reg = <0>;

	port {
		u-boot,dm-pre-reloc;
		panel_dsi_in: endpoint {
			u-boot,dm-pre-reloc;
			  remote-endpoint = <&dsi0_out>;
		  };
	};

	display-timings {
		native-mode = <&timing2>;
		u-boot,dm-pre-reloc;
		timing2: timing2 {
			clock-frequency = <50000000>;
			hactive = <800>;
			vactive = <1280>;
			hback-porch = <50>;
			hfront-porch = <100>;
			hsync-len = <20>;
			vback-porch = <20>;
			vfront-porch = <24>;
			vsync-len = <4>;
			de-active = <1>;
			pixelclk-active = <1>;
			u-boot,dm-pre-reloc;
		};
	};
};

&fb0 {
	artinchip,uboot-logo-on=<1>;
	u-boot,dm-pre-reloc;
	port {
		fb0_out: endpoint {
			remote-endpoint = <&de0_in>;
			u-boot,dm-pre-reloc;
		};
	};
};

&de0 {
	status = "okay";
	u-boot,dm-pre-reloc;

	port@0 {
		reg = <0>;
		u-boot,dm-pre-reloc;
		de0_in: endpoint {
			remote-endpoint = <&fb0_out>;
			u-boot,dm-pre-reloc;
		};
	};

	port@1 {
		reg = <1>;
		u-boot,dm-pre-reloc;
		de0_out: endpoint {
			remote-endpoint = <&dsi0_in>;
			u-boot,dm-pre-reloc;
		};
	};
};

&dsi0 {
	pinctrl-names = "default";
	pinctrl-0 = <&dsi_pins>;
	status = "okay";
	u-boot,dm-pre-reloc;

	data-lanes = <0 1 2 3>;
	lane-polarities = <0 0 0 0>;
	

	port@0 {
		reg = <0>;
		u-boot,dm-pre-reloc;
		dsi0_in: endpoint {
			remote-endpoint = <&de0_out>;
			u-boot,dm-pre-reloc;
		};
	};

	port@1 {
		reg = <1>;
		u-boot,dm-pre-reloc;
		dsi0_out: endpoint {
			remote-endpoint = <&panel_dsi_in>;
			u-boot,dm-pre-reloc;
		};
	};
};

/*

static int panel_enable(struct aic_panel *panel)
{
	struct simple *simple = panel_to_simple(panel);

	if (simple->reset) {
		gpiod_direction_output(simple->reset, 1);
		aic_delay_ms(10);
		gpiod_direction_output(simple->reset, 0);
		aic_delay_ms(120);
		gpiod_direction_output(simple->reset, 1);
		aic_delay_ms(120);
	}

	panel_di_enable(panel, 0);
	panel_dsi_send_perpare(panel);

	panel_dsi_dcs_send_seq(panel, 0x00, 0x00);
	panel_dsi_dcs_send_seq(panel, 0xFF, 0x10, 0x80, 0x01);
	panel_dsi_dcs_send_seq(panel, 0x00, 0x80);
	panel_dsi_dcs_send_seq(panel, 0xFF, 0x10, 0x80);
	panel_dsi_dcs_send_seq(panel, 0x00, 0x81);
	panel_dsi_dcs_send_seq(panel, 0xA4, 0x01);
	panel_dsi_dcs_send_seq(panel, 0x11);
	aic_delay_ms(200);
	panel_dsi_dcs_send_seq(panel, 0x29);
	aic_delay_ms(120);

	panel_dsi_setup_realmode(panel);

	panel_de_timing_enable(panel, 0);
	panel_backlight_enable(panel, 0);
	return 0;
}

static struct panel_dsi dsi = {
	.format = DSI_FMT_RGB888,
	.mode = DSI_MOD_VID_BURST,
	.lane_num = 4,
};

*/