痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

  人人好,我是痞子衡,是正经搞手艺的痞子。今天痞子衡给人人分享的是i.MXRT1060上LCD横向渐变色显示出亮点问题的剖析解决履历

  接上篇《一个关于LCD屏显示出异常亮点的故事(上)》咱们继续聊,上一篇发出之后,人人在我的微信公号文章下面留言很热烈,大部分同伙都把嫌疑点放在了HyperRAM时序设置上,以为很大概率是HyperRAM的数据接见出了问题导致了LCD显示异常,这个嫌疑是异常通情达理的,那么从高效定位问题的角度,我们接下来应该怎么做?

一、问题剖析

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

  让我们回到上一篇的最后,痞子衡列出了所有可能出问题的地方,我们现在需要将这些疑点逐一清扫:

  1. 客户LCD显示测试代码逻辑是否有问题?
  2. 客户LCD屏与i.MXRT1060毗邻(线序)是否有问题?
  3. 客户LCD屏的ST7701S驱动移植(从STM32到i.MXRT1060)是否有问题?
  4. 客户选用的HyperRAM自己质量是否有问题?
  5. i.MXRT1060设置的客户HyperRAM时序参数是否有问题?
  6. i.MXRT1060的LCD显示模块eLCDIF驱动是否有问题?
  7. i.MXRT1060系统的总线处置(如Cache、总线竞争)是否有问题?

  这些嫌疑点总结下来就是两类,一类是硬件问题(如2、4),另一类是软件问题(如1、3、5、6、7)。痞子衡以为应该从软件疑点先下手。由于从征象上看,硬件上基本没啥大问题,LCD是能够按代码设计那样去显示的,而且硬件问题检查起来(可能涉及改板子或者焊接,万一整坏了板子…)不如验证软件问题来得快,等软件疑点开端清扫了,再找硬件问题也不迟。
  确定了从软件疑点下手,那么从哪一个最先呢?当然是人人都以为最可疑的点 – HyperRAM时序设置问题这点先入手,不外直接去检查HyperRAM时序设置较为繁琐,我们有更好的选择,uint32_t s_frameBuffer[480][480]总巨细为900KB,这小于i.MXRT1060内部RAM总空间(1MB),以是我们完全可以将这个frameBuffer链接到内部RAM里来规避HyperRAM时序设置问题(疑点5)以及系统总线处置问题(疑点7),另外我们还可以直接用J-Link修改内部RAM里的frameBuffer数据来规避客户测试代码逻辑问题(疑点1)。为了方便地天生frameBuffer数据,我们还需要写个简朴的Python剧本,那么我们先尝试用这一套方式在LCD上显示一个真实景物照吧。

Note: 这套验证方式的最大利益是高效且省时,不需要在App代码工程里改frameBuffer相关代码以及一次次地重新编译下载。

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

二、最先测试

2.1 将frameBuffer链接到内部RAM里

2.1.1 重配FlexRAM

  首先是需要在App工程的startup_MIMXRT1062.s文件里修改Reset_Handler代码,增添FlexRAM重配代码,由于默认RAM设置是128KB ITCM, 128KB DTCM, 768KB OCRAM,我们要将其调整为1MB OCRAM。

__iomux_gpr16_adr     EQU  0x400AC040
__iomux_gpr17_adr     EQU  0x400AC044
__flexram_bank_cfg    EQU  0x55555555

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Default interrupt handlers.
;;
        THUMB

        PUBWEAK Reset_Handler
        SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
        CPSID   I               ; Mask interrupts

        ;新增代码(最先)
        LDR R0,=__iomux_gpr17_adr
        MOV32 R1,__flexram_bank_cfg
        STR R1,[R0]
        LDR R0,=__iomux_gpr16_adr
        LDR R1,[R0]
        ORR R1,R1,#4
        STR R1,[R0]
        ;新增代码(竣事)

        LDR     R0, =0xE000ED08
        LDR     R1, =__vector_table
        ; ...
2.1.2 调整MPU设置

  然后我们要在App工程的board.c文件里修改BOARD_ConfigMPU()函数,增添如下代码,确保所有1MB OCRAM地址空间(0x20200000最先)都是non-cacheable属性。

/* Region 6 setting: Memory with Normal type, not shareable, non-cacheable */
MPU->RBAR = ARM_MPU_RBAR(6, 0x20200000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1MB);
2.1.3 修改链接文件

  最后我们要在App工程的main函数源文件里将s_frameBuffer放在一个自界说的.frameBuffer段里,以便在App链接文件里将其放到OCRAM地址空间里(0x20200000 – 0x202FFFFF)。
  main函数源文件中的修改:

__no_init   uint32_t s_frameBuffer[APP_IMG_HEIGHT][APP_IMG_WIDTH] @ ".frameBuffer";

  App工程链接文件中的修改:

define symbol m_data2_start  = 0x20200000;
define symbol m_data2_end    = 0x202FFFFF;

define region DATA2_region = mem:[from m_data2_start to m_data2_end];

place in DATA2_region        { section .frameBuffer };

2.2 编写Python剧本天生frameBuffer数据

2.2.1 景物图片数据

  我们可以从网上找一张.jpg花样图片,将其尺寸裁剪到480×480,然后借助Pillow里的Image库将其转成XRGB8888花样的binary文件,对应Python剧本(剧本名为convert_jpeg_to_xrgb8888.py)用法和源代码如下:

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

import sys, os
import argparse
from PIL import Image

class ConvertJpegToXrgb8888(object):
    def __init__(self):
        pass

    def _read_options(self):
        parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
        parser.add_argument("-o", "--output", required=True, metavar="PATH", type=argparse.FileType('wb'), help="Specify the output file.")
        parser.add_argument("input", help="JPEG Image file."),
        return parser.parse_args()

    def run(self):
        args = self._read_options()
        imgObj = Image.open(args.input)
        pixelBuf = imgObj.getdata()
        for i in range(len(pixelBuf)):
            for j in range(len(pixelBuf[i])):
                args.output.write(chr(pixelBuf[i][len(pixelBuf[i]) - j - 1]))
            args.output.write(chr(0))
        args.output.close()

if __name__ == "__main__":
    exit(ConvertJpegToXrgb8888().run())
2.2.2 RGB测试数据

  此外我们还需要一个剧本,能够很容易地修改天生指定的RGB测试数据,用于定位亮点问题,对应Python剧本(剧本名为generate_xrgb8888.py)用法和源代码如下:

走近源码:Redis如何清除过期key

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

import sys, os
import argparse

class GenerateXrgb8888(object):
    def __init__(self):
        pass

    def _read_options(self):
        parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
        parser.add_argument("-o", "--output", required=True, metavar="PATH", type=argparse.FileType('wb'), help="Specify the output file.")
        return parser.parse_args()

    def _make_xrgb8888(self, r, g, b):
        return chr(b) + chr(g) + chr(r) + chr(0)

    def run(self):
        args = self._read_options()
        for i in range(160):
            for j in range(480):
                args.output.write(self._make_xrgb8888(j%256, 0, 0))
        for i in range(160):
            for j in range(480):
                args.output.write(self._make_xrgb8888(0, j%256, 0))
        for i in range(160):
            for j in range(480):
                args.output.write(self._make_xrgb8888(0, 0, j%256))
        args.output.close()

if __name__ == "__main__":
    exit(GenerateXrgb8888().run())

2.3 使用J-Link将frameBuffer数据更新进OCRAM

2.3.1 显示景物图片

  我们从网上随便找一张景物图片scenery.jpg,使用convert_jpeg_to_xrgb8888.py剧本将其转换为scenery.bin,然后将J-Link仿真器挂上芯片,乐成毗邻之后,使用loadbin scenery.bin 0x20200000下令将图片数据下载进内部RAM。

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

  这时刻你可以看到LCD的显示变成了图片:

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

2.3.2 显示RGB测试数据

  从上一节测试的真实图片显示效果上看,似乎看不出显著的亮点问题,这说明亮点在特定RGB数据内容显示的时刻才会展现出来,那么我们现在的义务就是要找到这个展现条件,这时刻需要修改generate_xrgb8888.py剧原本频频做实验。
  以是痞子衡就不断地修改剧本、天生数据、下载数据,功夫不负有心人,痞子衡找到了亮点复现纪律。

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

三、缘故原由剖析

  痞子衡发现的亮点纪律是当横向某两个延续渐变像素点RGB任一分量泛起多bit由1向0跳变时(比如前一个像素点B分量是8’b01111111,后一个像素点B分量是8’b10000000),则后一个像素点必是亮点,这个亮点像素点最终显示的B分量极可能变成了8’b11111111。

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

  以是剖析下来应该是DCLK信号的极性设置在屏的驱动IC和i.MXRT1060的eLCDIF模块里不匹配,RGB数据线采样时机错了,导致现实显示的RGB数据发生了错误。
  在SDK的elcdif_rgb example里关于eLCDIF模块信号输出的极性设置如下,这里需要注重的是kELCDIF_DriveDataOnRisingClkEdge是置1(即上沿数据输出,下沿数据保持的意思)。

#define APP_POL_FLAGS (kELCDIF_DataEnableActiveHigh | kELCDIF_VsyncActiveLow | kELCDIF_HsyncActiveLow | kELCDIF_DriveDataOnRisingClkEdge)

  这是i.MXRT1060 eLCDIF极性设置相关:

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

  这是OTA5180A芯片的默认极性设置时序图:

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

  SDK里的极性设置与i.MXRT1060-EVK标配的LCD屏(RK043FN02H-CT)里的驱动芯片OTA5180A默认设置是相吻合的。
  我们现在再来看看SDK里的极性设置与客户LCD屏的驱动芯片ST7701S的极性设置是否匹配,客户设置了ST7701S的IM[3:0]状态为4’b1010,即RGB模式输出,且PCLK是下沿数据输入,上沿数据保持(Latch),因此跟SDK里的极性设置是反相的。

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

  以是最终的解决方式就是要么将ST7701S的IM[3:0]状态设为4’b0010,要么在App代码里将APP_POL_FLAGS界说改用kELCDIF_DriveDataOnFallingClkEdge。

迎接订阅

文章会同时公布到我的 博客园主页CSDN主页微信民众号 平台上。

微信搜索”痞子衡嵌入式“或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:纪录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(解答篇)

原创文章,作者:870t新闻网,如若转载,请注明出处:https://www.870t.com/archives/3646.html