查看: 2100|回复: 4

[分享] 基于i.MX RT1052 Aworks 测试PXP图像混合功能

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3300

    主题

    6547

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32035
    最后登录
    2024-4-26
    发表于 2022-3-16 15:32:23 | 显示全部楼层 |阅读模式


    这次评估RT1052 PXP的图像混合功能,记录了本次的开发日记。


    1. 首先阅读芯片手册
    14.png
    说一下本人粗看该章节之后的感想,很少会极其详细查看芯片的手册,只要在遇到难以解决的问题时,才会详细看芯片手册,但是有一点就是模块的内部架构及相关参数还是要大体了解的,其实和编程接口是相关的,如果不了解这些信息的话,虽然会使用API进行编程,但是实际一旦遇到问题是缺少理论支撑,排查问题就会难一些。


    2. 设备宏开关
    在前面支持LCD的章节当中,其实PXP的设备宏开关就一起打开了。我们只要先把样例跑起来,就可以两个图像混合评估,即一秒内能做多少次两个满屏图像的混合。
    15.png
    3. 测试
    在目录examples\peripheral\m105x\pxp\demo_pxp_blend.c 为默认支持RGB565的样例。把相关input/output参数改为支持RGB24的即可,需要注意的话,对于PXP模块所需要input数据源为RGBA,它需要的时32位的数据,这个是需要注意的地方,否则会产生异常。
    16.png
    4. 总结
    PXP输入、输出的数据源格式是最重要的,否则花屏,闪屏的现象会出现。希望大家别踏坑。本人设置的输入数据源为RGBA,输出为RGB.如下为笔者的测试代码。
    1. /*******************************************************************************
    2. *                                  AWorks
    3. *                       ----------------------------
    4. *                       innovating embedded platform
    5. *
    6. * Copyright (c) 2001-2017 Guangzhou ZHIYUAN Electronics Co., Ltd.
    7. * All rights reserved.
    8. *
    9. * Contact information:
    10. * web site:    http://www.zlg.cn
    11. * e-mail:      support@zlg.cn
    12. *******************************************************************************/

    13. /**
    14. * \file
    15. * \brief PXP像素处理例程
    16. *
    17. * - 操作步骤:
    18. *   1. 本例程需在aw_prj_params.h头文件里使能
    19. *      - 显示屏设备宏
    20. *      - 如果使用800 X 480显示屏,打开TEST_SCREEN_BIG,否则打开TEST_SCREEN_LITTER;
    21. *   2. 连接串口设备
    22. *
    23. * - 实验现象:
    24. *   1.蓝色矩形和黄色矩形在屏幕上移动,交汇界面为白色。
    25. */

    26. #include <stdio.h>
    27. #include <string.h>
    28. #include "aworks.h"
    29. #include "aw_delay.h"
    30. #include "aw_vdebug.h"
    31. #include "aw_fb.h"
    32. #include "aw_demo_config.h"
    33. #include "aw_cache.h"
    34. #include "aw_mem.h"
    35. #include "driver/pxp/awbl_imx1050_pxp.h"

    36. typedef struct pixel_24bpp {
    37.   uint8_t b;
    38.   uint8_t g;
    39.   uint8_t r;
    40.         uint8_t a;
    41. } pixel_24bpp_t;

    42. //#define TEST_SCREEN_BIG             /*800 X 480显示屏*/
    43. #define TEST_SCREEN_LITTER          /*480 X 1920显示屏*/

    44. #ifdef TEST_SCREEN_BIG
    45. #define __APP_IMG_HEIGHT  480
    46. #define __APP_IMG_WIDTH   800
    47. #else
    48. #define __APP_IMG_HEIGHT  1920
    49. #define __APP_IMG_WIDTH   480
    50. #endif

    51. /* 定义全局的 frame buffer 设备 */
    52. static aw_fb_fix_info_t __fix_screen_info;
    53. static aw_fb_var_info_t __var_info;

    54. static uint8_t  *__gp_ps_buf;
    55. static uint8_t  *__gp_as_buf;

    56. /* PXP 输出 buffer 配置. */
    57. static pxp_output_buffer_config_t __g_output_buffer_config;

    58. /*像素深度*/
    59. #define __APP_BPP         3

    60. #define __APP_PS_WIDTH    (__APP_IMG_WIDTH  / 2)
    61. #define __APP_PS_HEIGHT   (__APP_IMG_HEIGHT / 2)

    62. #define __APP_AS_WIDTH    (__APP_IMG_WIDTH  / 2)
    63. #define __APP_AS_HEIGHT   (__APP_IMG_HEIGHT / 2)

    64. #define __APP_PS_ULC_X    ((__APP_IMG_WIDTH  / 2) - (__APP_PS_SIZE / 2))
    65. #define __APP_PS_ULC_Y    ((__APP_IMG_HEIGHT / 2) - (__APP_PS_SIZE / 2))
    66. #define __APP_PS_LRC_X    ((__APP_IMG_WIDTH  / 2) + (__APP_PS_SIZE / 2) - 1)

    67. static aw_err_t __fb_init (void)
    68. {
    69.     void * p_fb = aw_fb_open(DE_FB, 0);
    70.     if (p_fb == NULL) {
    71.         aw_kprintf("open fb fail.\r\n");
    72.         return -AW_ERROR;
    73.     }

    74.     /* frame buffer 初始化 */
    75.     aw_fb_init(p_fb);

    76.     /*frame buffer 设备信息货物*/
    77.     aw_fb_ioctl(p_fb, AW_FB_CMD_GET_FINFO, &__fix_screen_info);
    78.     aw_fb_ioctl(p_fb, AW_FB_CMD_GET_VINFO, &__var_info);
    79.     /* 设置背光亮度 */
    80.     aw_fb_backlight(p_fb, 99);
    81.     aw_fb_start(p_fb);
    82.     /* 初始化屏幕背景色(白色) */
    83.     memset((void *)__fix_screen_info.vram_addr,
    84.            0xFF,
    85.            __var_info.buffer.buffer_size * __var_info.buffer.buffer_num);

    86.     return AW_OK;
    87. }


    88. static void __as_ps_buf_init (void)
    89. {
    90.     uint32_t i, j;
    91.     pixel_24bpp_t *ps_buf = (pixel_24bpp_t *)__gp_ps_buf;
    92.     pixel_24bpp_t *as_buf = (pixel_24bpp_t *)__gp_as_buf;

    93.     /* The PS buffer is BLUE rectangle, the AS buffer is YELLOW rectangle. */
    94.     for (i = 0; i < __APP_PS_HEIGHT; i++) {
    95.         for (j = 0; j < __APP_PS_WIDTH; j++) {
    96.             ps_buf[i * __APP_PS_WIDTH +  j].b = 0xFF;
    97.                                           ps_buf[i * __APP_PS_WIDTH +  j].g = 0x00;
    98.                                           ps_buf[i * __APP_PS_WIDTH +  j].r = 0x00;
    99.         }
    100.     }

    101.     for (i = 0; i < __APP_AS_HEIGHT; i++) {
    102.         for (j = 0; j < __APP_AS_WIDTH; j++) {
    103.             as_buf[i * __APP_AS_WIDTH +  j].b = 0x00;
    104.                                           as_buf[i * __APP_AS_WIDTH +  j].g = 0xFF;
    105.                                           as_buf[i * __APP_AS_WIDTH +  j].r = 0xFF;
    106.         }
    107.     }

    108. }


    109. static void __app_pxp_config (void)
    110. {
    111.     /* PS configure. */
    112.     const pxp_ps_buffer_config_t ps_buffer_config = {
    113.         .pixel_format   = kPXP_PsPixelFormatRGB888,
    114.         .swap_byte      = 0,
    115.         .buffer_addr    = (uint32_t)__gp_ps_buf,
    116.         .buffer_addr_u  = 0,
    117.         .buffer_addr_v  = 0,
    118.         .pitch_bytes    = __APP_PS_WIDTH * __APP_BPP,
    119.     };

    120.     /* 复位PXP */
    121.     pxp_hard_reset();

    122.     /* 设置PS背景颜色 */
    123.     pxp_set_process_surface_back_ground_color(0x00);

    124.     /* 配置PS buffer */
    125.     pxp_set_process_surface_buffer_config(&ps_buffer_config);

    126.     /* AS config. */
    127.     const pxp_as_buffer_config_t as_buffer_config = {
    128.         .pixel_format = kPXP_AsPixelFormatRGB888,
    129.         .buffer_addr  = (uint32_t)__gp_as_buf,
    130.         .pitch_bytes  = __APP_AS_WIDTH * __APP_BPP,
    131.     };

    132.     /*配置AS buffer*/
    133.     pxp_set_alpha_surface_buffer_config(&as_buffer_config);

    134.     /*AS blend config*/
    135.     const pxp_as_blend_config_t as_blend_config = {
    136.         .alpha          = 0,
    137.         .invert_alpha   = 0,
    138.         .alpha_mode     = kPXP_AlphaRop,
    139.         .rop_mode       = kPXP_RopMergeAs
    140.     };

    141.     /*设置AS blend*/
    142.     pxp_set_alpha_surface_blend_config(&as_blend_config);

    143.     /* Output config. */
    144.     __g_output_buffer_config.pixel_format    = kPXP_OutputPixelFormatRGB888P;
    145.     __g_output_buffer_config.interlaced_mode = kPXP_OutputProgressive;
    146.     __g_output_buffer_config.buffer0_addr    = (uint32_t)__fix_screen_info.vram_addr;
    147.     __g_output_buffer_config.buffer1_addr    = 0;
    148.     __g_output_buffer_config.pitch_bytes     = __APP_IMG_WIDTH * 3;
    149.     __g_output_buffer_config.width           = __APP_IMG_WIDTH;
    150.     __g_output_buffer_config.height          = __APP_IMG_HEIGHT;

    151.     /*配置输出pxp buffer*/
    152.     pxp_set_output_buffer_config(&__g_output_buffer_config);

    153.     /* 禁能 CSC1 */
    154.     pxp_enable_csc1(0);
    155. }



    156. static void __app_blend (void)
    157. {
    158.     uint8_t buf_index = 0U;

    159.     /*a pointer to a array*/
    160.     uint8_t (*p_vddr)[__APP_IMG_WIDTH * __APP_IMG_HEIGHT * __APP_BPP] = NULL;

    161.     int8_t ps_inc_x = 1;
    162.     int8_t ps_inc_y = 1;
    163.     int8_t as_inc_x = -1;
    164.     int8_t as_inc_y = -1;
    165.     uint16_t ps_ulc_x = 0U;
    166.     uint16_t ps_ulc_y = 0U;
    167.     uint16_t as_ulc_x = __APP_IMG_WIDTH - __APP_AS_WIDTH;
    168.     uint16_t as_ulc_y = __APP_IMG_HEIGHT - __APP_AS_HEIGHT;
    169.     uint16_t ps_lrc_x, ps_lrc_y, as_lrc_x, as_lrc_y;

    170.     ps_lrc_x = ps_ulc_x + __APP_PS_WIDTH - 1U;
    171.     ps_lrc_y = ps_ulc_y + __APP_PS_HEIGHT - 1U;
    172.     as_lrc_x = as_ulc_x + __APP_AS_WIDTH - 1U;
    173.     as_lrc_y = as_ulc_y + __APP_AS_HEIGHT - 1U;

    174.     p_vddr = (void *)__fix_screen_info.vram_addr;

    175.     while (1) {

    176.         /*将buffer放入缓存中*/
    177.         aw_cache_flush((void *)__gp_ps_buf, __APP_PS_HEIGHT *  __APP_PS_WIDTH * __APP_BPP);
    178.         aw_cache_flush((void *)__gp_as_buf, __APP_AS_HEIGHT *  __APP_AS_WIDTH * __APP_BPP);

    179.         /*PS图形位置*/
    180.         pxp_set_process_surface_position(ps_ulc_x, ps_ulc_y, ps_lrc_x, ps_lrc_y);

    181.         /*AS图形位置*/
    182.         pxp_set_alpha_surface_position(as_ulc_x, as_ulc_y, as_lrc_x, as_lrc_y);

    183.         /*配置输出buffer的显存地址*/
    184.         __g_output_buffer_config.buffer0_addr = (uint32_t)p_vddr[buf_index];
    185.         pxp_set_output_buffer_config(&__g_output_buffer_config);

    186.         /* Start PXP. */
    187.         pxp_start();

    188.         /* 等待PXP图形处理完成 */
    189.         pxp_complete_status_sync();

    190.         /*清空缓存中的buffer*/
    191.         aw_cache_invalidate((void *)__gp_ps_buf, __APP_PS_HEIGHT *  __APP_PS_WIDTH * __APP_BPP);
    192.         aw_cache_invalidate((void *)__gp_as_buf, __APP_AS_HEIGHT *  __APP_AS_WIDTH * __APP_BPP);

    193.         aw_cache_flush(
    194.             (void*)p_vddr[buf_index],
    195.             __var_info.buffer.buffer_size * __var_info.buffer.buffer_num);

    196.         /*切换显存*/
    197.         buf_index++;
    198.         if (buf_index >= __var_info.buffer.buffer_num) {
    199.             buf_index = 0;
    200.         }

    201.         ps_lrc_x += ps_inc_x;
    202.         ps_lrc_y += ps_inc_y;
    203.         as_lrc_x += as_inc_x;
    204.         as_lrc_y += as_inc_y;

    205.         ps_ulc_x += ps_inc_x;
    206.         ps_ulc_y += ps_inc_y;
    207.         as_ulc_x += as_inc_x;
    208.         as_ulc_y += as_inc_y;

    209.         if (0 == as_ulc_x) {
    210.             as_inc_x = 1;
    211.         } else if (__APP_IMG_WIDTH - 1 == as_lrc_x) {
    212.             as_inc_x = -1;
    213.         }

    214.         if (0 == as_ulc_y) {
    215.             as_inc_y = 1;
    216.         } else if (__APP_IMG_HEIGHT - 1 == as_lrc_y) {
    217.             as_inc_y = -1;
    218.         }

    219.         if (0 == ps_ulc_x) {
    220.             ps_inc_x = 1;
    221.         } else if (__APP_IMG_WIDTH - 1 == ps_lrc_x) {
    222.             ps_inc_x = -1;
    223.         }

    224.         if (0 == ps_ulc_y) {
    225.             ps_inc_y = 1;
    226.         } else if (__APP_IMG_HEIGHT - 1 == ps_lrc_y) {
    227.             ps_inc_y = -1;
    228.         }
    229.         aw_mdelay(50);
    230.     }
    231. }


    232. void demo_pxp_blend (void)
    233. {
    234.     /* 初始化fram buffer */
    235.     aw_err_t ret = __fb_init();
    236.     if(ret != AW_OK){
    237.         aw_kprintf("fb init fail.\r\n");
    238.         return;
    239.     }
    240.     extern void lt9211_init();
    241.                 lt9211_init();
    242.     __gp_ps_buf = (uint8_t *) aw_mem_align(__APP_PS_WIDTH * __APP_PS_HEIGHT * __APP_BPP,
    243.                                            AW_CACHE_LINE_SIZE);
    244.     __gp_as_buf = (uint8_t *) aw_mem_align(__APP_AS_WIDTH * __APP_AS_HEIGHT * __APP_BPP,
    245.                                            AW_CACHE_LINE_SIZE);
    246.     if (NULL == __gp_ps_buf || __gp_as_buf == NULL) {
    247.         aw_kprintf("aw_mem_align error.\r\n");
    248.         return ;
    249.     }

    250.     /* 初始化buffer */
    251.     __as_ps_buf_init();

    252.     /* 配置pxp */
    253.     __app_pxp_config();

    254.     /* blend测试 */
    255.     __app_blend();

    256.     aw_mem_free(__gp_ps_buf);
    257.     aw_mem_free(__gp_as_buf);
    258. }

    259. /* end of file */
    复制代码


    签到签到
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 00:06
  • 签到天数: 1941 天

    [LV.Master]伴坛终老

    61

    主题

    1万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    17305
    最后登录
    2024-4-27
    发表于 2022-3-16 17:48:42 | 显示全部楼层
    学习学习
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 19:12
  • 签到天数: 840 天

    [LV.10]以坛为家III

    5

    主题

    5714

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    6949
    最后登录
    2024-4-27
    发表于 2022-3-17 10:25:51 | 显示全部楼层
    搞块板学习学习
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 21:56
  • 签到天数: 1212 天

    [LV.10]以坛为家III

    22

    主题

    4768

    帖子

    0

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    8090

    活跃会员

    最后登录
    2024-4-27
    发表于 2022-3-17 11:12:08 | 显示全部楼层
    你猜这是日天写的吗
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3300

    主题

    6547

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32035
    最后登录
    2024-4-26
     楼主| 发表于 2022-3-17 18:24:58 | 显示全部楼层
    lospring 发表于 2022-3-17 11:12
    你猜这是日天写的吗

    肯定是
    签到签到
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-4-28 06:17 , Processed in 0.127616 second(s), 24 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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