查看: 3811|回复: 2

[原创] Crank Storyboard工程显示异常解决

[复制链接]

该用户从未签到

715

主题

6374

帖子

0

超级版主

Rank: 8Rank: 8

积分
25213
最后登录
2025-8-18
发表于 2021-7-28 13:57:42 | 显示全部楼层 |阅读模式
问题现象

客户正在开发的项目想使用Crank[1]做LCD GUI界面,所以使用MIMXRT1050开发板和SDK library提供的Crank工程做功能验证与评估,在此过程中,他们注意到显示屏(RK043FN02H-CT)最左上角的(0,0)像素点显示为白色或者绿色(如下图所示),并且这个现象在测试Coffee Machine和Home Controls工程时都有复现,但并未出现在LVGL和emWin相关的工程中,所以客户怀疑此现象与硬件无关,猜测与SDK library中的PXP驱动有关。

2dd16307-33fe-4e3f-8bd0-96c1a84ddc4c.png

图 1

问题分析与解决

小编根据客户的描述复现了上述问题现象,并在经过如下测试步骤后,基本认同客户的猜测,认为问题与硬件设计无关,并在与AE team沟通后,确认问题现象确与PXP驱动相关,导致gr_generic_display_update()函数更新LCD时,数组值有错码。

  • 降低LCD的DCLK频率
  • 采用更稳定的外置电源供电
  • 在IAR、MCUXpresso都有复现问题现象

解决方式有两种(如下图所示),第一种为使能ping-pong模式的双buffer缓存机制,以空间换时间,交替将显示数据传给LCD,这样的话,可以舍弃PXP模块,第二种方法是在原有程序基础上,修改PXP驱动,代码修改量相对较小。

76c821b4-5271-4317-b5b2-e0314a4e5a3d.png

图 2

修改后代码如下所示,允许开发者可以通过宏 #define APP_USE_PXP x 自主选择上述两种解决方式的任何一种。

  1. #define APP_USE_PXP  1

  2. /*
  3. * Configure the PXP block to handle the framebuffer transfer in hardware.
  4. *
  5. * We will assume 16bit RGB565 based framebuffer
  6. *  - The LCD peripheral is setup to use eLCDIF_Buffer[0]
  7. *  - Storyboard is configured to render single buffer, eLCDIF_Buffer[1]
  8. *  - The PXP will be configured to transfer from eLCDIF_Buffer[1] to eLCDIF_Buffer[0]
  9. */
  10. static void APP_InitPxp(void)
  11. {
  12.     PXP_Init(APP_PXP);

  13.     /* PS configure. */
  14.     const pxp_ps_buffer_config_t psBufferConfig = {
  15.         .pixelFormat = kPXP_PsPixelFormatRGB565,
  16.         .swapByte = false,
  17.         .bufferAddr = (uint32_t)eLCDIF_Buffer[1],
  18.         .bufferAddrU = 0U,
  19.         .bufferAddrV = 0U,
  20.         .pitchBytes = APP_IMG_WIDTH * APP_BPP,
  21.     };

  22.     PXP_SetProcessSurfaceBackGroundColor(APP_PXP, 0x1f);
  23.     PXP_SetProcessSurfaceBufferConfig(APP_PXP, &psBufferConfig);
  24.     PXP_SetProcessSurfacePosition(APP_PXP, 0, 0, APP_IMG_WIDTH, APP_IMG_HEIGHT);

  25.     /* Disable AS. */
  26.     PXP_SetAlphaSurfacePosition(APP_PXP, 0xFFFFU, 0xFFFFU, 0U, 0U);

  27.     /* Output config. */
  28.     outputBufferConfig.pixelFormat = kPXP_OutputPixelFormatRGB565;
  29.     outputBufferConfig.interlacedMode = kPXP_OutputProgressive;
  30.     outputBufferConfig.buffer0Addr = (uint32_t)eLCDIF_Buffer[0];
  31.     outputBufferConfig.buffer1Addr = 0U;
  32.     outputBufferConfig.pitchBytes = APP_IMG_WIDTH * APP_BPP;
  33.     outputBufferConfig.width = APP_IMG_WIDTH;
  34.     outputBufferConfig.height = APP_IMG_HEIGHT;

  35.     PXP_SetOutputBufferConfig(APP_PXP, &outputBufferConfig);

  36.     /* Disable CSC1, it is enabled by default. */
  37.     PXP_EnableCsc1(APP_PXP, false);
  38.     /* Process 16x16 pixel blocks - Note: make sure this is appropriate for the display geometry */
  39.     PXP_SetProcessBlockSize(APP_PXP, kPXP_BlockSize16);
  40. }

  41. int
  42. gr_generic_display_init(gr_generic_display_info_t *info) {

  43. BOARD_InitLcdifPixelClock();

  44. /* enable backlight */
  45. BOARD_InitLcd();

  46.     info->num_layers = 1;
  47.     info->layer_info = &main_layer;
  48. #if APP_USE_PXP
  49.     main_layer.num_buffers = 1;      // Single render buffer for Storyboard
  50.     main_layer.buffer[0] = (void *)eLCDIF_Buffer[1];
  51. #else
  52.     main_layer.num_buffers = 2;      // double (ping-pong) render buffers for Storyboard

  53.     main_layer.buffer[0] = (void *)eLCDIF_Buffer[0];

  54.     main_layer.buffer[1] = (void *)eLCDIF_Buffer[1];

  55. #endif
  56.     main_layer.render_format = GR_RENDER_FMT_RGB565;
  57.     main_layer.width = (uint16_t)APP_IMG_WIDTH;;
  58.     main_layer.height = (uint16_t)APP_IMG_HEIGHT;
  59.     main_layer.stride = (uint16_t)(main_layer.width * GR_RENDER_FMT_BYTESPP(main_layer.render_format));

  60.     ELCDIF_RgbModeInit(APP_ELCDIF, &eLCDIF_rgbConfig);
  61. #if APP_USE_PXP
  62.     /* configure PXP for hardware assisted framebuffer transfer */
  63.     APP_InitPxp();
  64. #else
  65.     /* Enable interrupt LCDIF_IRQn request in the NVIC. */
  66.     EnableIRQ(LCDIF_IRQn);
  67.     /* Enable interrupts */
  68.     ELCDIF_EnableInterrupts(ELCDIF_PERIPHERAL, (kELCDIF_CurFrameDoneInterruptEnable | kELCDIF_TxFifoUnderflowInterruptEnable));

  69. #endif
  70. ELCDIF_SetNextBufferAddr(APP_ELCDIF, (uint32_t)eLCDIF_Buffer[0]);
  71. ELCDIF_RgbModeStart(APP_ELCDIF);

  72. return 0;
  73. }

  74. int
  75. gr_generic_display_update(const gr_generic_display_info_t *info) {

  76. #if APP_USE_PXP
  77.     /* invalidate cache on the buffer about to be being written to LCD by pxp*/
  78. DCACHE_CleanInvalidateByRange((uint32_t)info->layer_info[0].buffer[info->layer_info[0].buffer_draw_index], APP_IMG_HEIGHT * APP_IMG_WIDTH * GR_RENDER_FMT_BYTESPP(info->layer_info[0].render_format) );

  79. /* Start PXP. */
  80. PXP_Start(APP_PXP);

  81. /* Wait for process complete. */
  82. while (!(kPXP_CompleteFlag & PXP_GetStatusFlags(APP_PXP))) {}

  83. PXP_ClearStatusFlags(APP_PXP, kPXP_CompleteFlag);
  84. #else
  85.     /* invalidate cache on the buffer about to be being written to LCD */
  86.     DCACHE_CleanInvalidateByRange((uint32_t)info->layer_info[0].buffer[info->layer_info[0].buffer_draw_index], APP_IMG_HEIGHT * APP_IMG_WIDTH * GR_RENDER_FMT_BYTESPP(info->layer_info[0].render_format) );
  87.     s_frame_done = false;
  88. ELCDIF_SetNextBufferAddr(APP_ELCDIF, (uint32_t)info->layer_info[0].buffer[info->layer_info[0].buffer_draw_index]);
  89.     while(s_frame_done == false) {}
  90. #endif
  91.     return 0;
  92. }
复制代码

欢迎留言和我分享你的疑惑和见解 ,也欢迎收藏或转发

[1]

Crank: https://www.cranksoftware.com/



回复

使用道具 举报

  • TA的每日心情
    开心
    2025-8-8 16:43
  • 签到天数: 1504 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    97

    主题

    4692

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    10093
    最后登录
    2025-8-8
    发表于 2021-7-28 14:11:43 | 显示全部楼层
    这问题怎么发现啊!
    这得多细心呀
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    715

    主题

    6374

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    25213
    最后登录
    2025-8-18
     楼主| 发表于 2021-7-28 17:50:28 | 显示全部楼层
    jobszheng5 发表于 2021-7-28 14:11
    这问题怎么发现啊!
    这得多细心呀

    是的,稍微不注意就会忽略掉了
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-20 03:48 , Processed in 0.073206 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表