本文主要是通过迁移的思维,记录本人初次使用周立功的Aworks框架进行BSP开发
做了这么长的开发以来,从来没有使用过GPU2D,GPU3G进行编程。这次评估RT1052 PXP的图像混合功能,记录了本次的开发日记。
1. 首先阅读芯片手册
说一下本人粗看该章节之后的感想,很少会极其详细查看芯片的手册,只要在遇到难以解决的问题时,才会详细看芯片手册,但是有一点就是模块的内部架构及相关参数还是要大体了解的,其实和编程接口是相关的,如果不了解这些信息的话,虽然会使用API进行编程,但是实际一旦遇到问题是缺少理论支撑,排查问题就会难一些。
2. 设备宏开关
在前面支持LCD的章节当中,其实PXP的设备宏开关就一起打开了。我们只要先把样例跑起来,就可以两个图像混合评估,即一秒内能做多少次两个满屏图像的混合。
3. 测试
在目录examples\peripheral\m105x\pxp\demo_pxp_blend.c 为默认支持RGB565的样例。把相关input/output参数改为支持RGB24的即可,需要注意的话,对于PXP模块所需要input数据源为RGBA,它需要的时32位的数据,这个是需要注意的地方,否则会产生异常。
4. 总结
PXP输入、输出的数据源格式是最重要的,否则花屏,闪屏的现象会出现。希望大家别踏坑。本人设置的输入数据源为RGBA,输出为RGB.如下为笔者的测试代码。
/*******************************************************************************
* AWorks
* ----------------------------
* innovating embedded platform
*
* Copyright (c) 2001-2017 Guangzhou ZHIYUAN Electronics Co., Ltd.
* All rights reserved.
*
* Contact information:
* web site: http://www.zlg.cn
* e-mail: support@zlg.cn
*******************************************************************************/
/**
* \file
* \brief PXP像素处理例程
*
* - 操作步骤:
* 1. 本例程需在aw_prj_params.h头文件里使能
* - 显示屏设备宏
* - 如果使用800 X 480显示屏,打开TEST_SCREEN_BIG,否则打开TEST_SCREEN_LITTER;
* 2. 连接串口设备
*
* - 实验现象:
* 1.蓝色矩形和黄色矩形在屏幕上移动,交汇界面为白色。
*/
#include <stdio.h>
#include <string.h>
#include "aworks.h"
#include "aw_delay.h"
#include "aw_vdebug.h"
#include "aw_fb.h"
#include "aw_demo_config.h"
#include "aw_cache.h"
#include "aw_mem.h"
#include "driver/pxp/awbl_imx1050_pxp.h"
typedef struct pixel_24bpp {
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} pixel_24bpp_t;
//#define TEST_SCREEN_BIG /*800 X 480显示屏*/
#define TEST_SCREEN_LITTER /*480 X 1920显示屏*/
#ifdef TEST_SCREEN_BIG
#define __APP_IMG_HEIGHT 480
#define __APP_IMG_WIDTH 800
#else
#define __APP_IMG_HEIGHT 1920
#define __APP_IMG_WIDTH 480
#endif
/* 定义全局的 frame buffer 设备 */
static aw_fb_fix_info_t __fix_screen_info;
static aw_fb_var_info_t __var_info;
static uint8_t *__gp_ps_buf;
static uint8_t *__gp_as_buf;
/* PXP 输出 buffer 配置. */
static pxp_output_buffer_config_t __g_output_buffer_config;
/*像素深度*/
#define __APP_BPP 3
#define __APP_PS_WIDTH (__APP_IMG_WIDTH / 2)
#define __APP_PS_HEIGHT (__APP_IMG_HEIGHT / 2)
#define __APP_AS_WIDTH (__APP_IMG_WIDTH / 2)
#define __APP_AS_HEIGHT (__APP_IMG_HEIGHT / 2)
#define __APP_PS_ULC_X ((__APP_IMG_WIDTH / 2) - (__APP_PS_SIZE / 2))
#define __APP_PS_ULC_Y ((__APP_IMG_HEIGHT / 2) - (__APP_PS_SIZE / 2))
#define __APP_PS_LRC_X ((__APP_IMG_WIDTH / 2) + (__APP_PS_SIZE / 2) - 1)
static aw_err_t __fb_init (void)
{
void * p_fb = aw_fb_open(DE_FB, 0);
if (p_fb == NULL) {
aw_kprintf("open fb fail.\r\n");
return -AW_ERROR;
}
/* frame buffer 初始化 */
aw_fb_init(p_fb);
/*frame buffer 设备信息货物*/
aw_fb_ioctl(p_fb, AW_FB_CMD_GET_FINFO, &__fix_screen_info);
aw_fb_ioctl(p_fb, AW_FB_CMD_GET_VINFO, &__var_info);
/* 设置背光亮度 */
aw_fb_backlight(p_fb, 99);
aw_fb_start(p_fb);
/* 初始化屏幕背景色(白色) */
memset((void *)__fix_screen_info.vram_addr,
0xFF,
__var_info.buffer.buffer_size * __var_info.buffer.buffer_num);
return AW_OK;
}
static void __as_ps_buf_init (void)
{
uint32_t i, j;
pixel_24bpp_t *ps_buf = (pixel_24bpp_t *)__gp_ps_buf;
pixel_24bpp_t *as_buf = (pixel_24bpp_t *)__gp_as_buf;
/* The PS buffer is BLUE rectangle, the AS buffer is YELLOW rectangle. */
for (i = 0; i < __APP_PS_HEIGHT; i++) {
for (j = 0; j < __APP_PS_WIDTH; j++) {
ps_buf[i * __APP_PS_WIDTH + j].b = 0xFF;
ps_buf[i * __APP_PS_WIDTH + j].g = 0x00;
ps_buf[i * __APP_PS_WIDTH + j].r = 0x00;
}
}
for (i = 0; i < __APP_AS_HEIGHT; i++) {
for (j = 0; j < __APP_AS_WIDTH; j++) {
as_buf[i * __APP_AS_WIDTH + j].b = 0x00;
as_buf[i * __APP_AS_WIDTH + j].g = 0xFF;
as_buf[i * __APP_AS_WIDTH + j].r = 0xFF;
}
}
}
static void __app_pxp_config (void)
{
/* PS configure. */
const pxp_ps_buffer_config_t ps_buffer_config = {
.pixel_format = kPXP_PsPixelFormatRGB888,
.swap_byte = 0,
.buffer_addr = (uint32_t)__gp_ps_buf,
.buffer_addr_u = 0,
.buffer_addr_v = 0,
.pitch_bytes = __APP_PS_WIDTH * __APP_BPP,
};
/* 复位PXP */
pxp_hard_reset();
/* 设置PS背景颜色 */
pxp_set_process_surface_back_ground_color(0x00);
/* 配置PS buffer */
pxp_set_process_surface_buffer_config(&ps_buffer_config);
/* AS config. */
const pxp_as_buffer_config_t as_buffer_config = {
.pixel_format = kPXP_AsPixelFormatRGB888,
.buffer_addr = (uint32_t)__gp_as_buf,
.pitch_bytes = __APP_AS_WIDTH * __APP_BPP,
};
/*配置AS buffer*/
pxp_set_alpha_surface_buffer_config(&as_buffer_config);
/*AS blend config*/
const pxp_as_blend_config_t as_blend_config = {
.alpha = 0,
.invert_alpha = 0,
.alpha_mode = kPXP_AlphaRop,
.rop_mode = kPXP_RopMergeAs
};
/*设置AS blend*/
pxp_set_alpha_surface_blend_config(&as_blend_config);
/* Output config. */
__g_output_buffer_config.pixel_format = kPXP_OutputPixelFormatRGB888P;
__g_output_buffer_config.interlaced_mode = kPXP_OutputProgressive;
__g_output_buffer_config.buffer0_addr = (uint32_t)__fix_screen_info.vram_addr;
__g_output_buffer_config.buffer1_addr = 0;
__g_output_buffer_config.pitch_bytes = __APP_IMG_WIDTH * 3;
__g_output_buffer_config.width = __APP_IMG_WIDTH;
__g_output_buffer_config.height = __APP_IMG_HEIGHT;
/*配置输出pxp buffer*/
pxp_set_output_buffer_config(&__g_output_buffer_config);
/* 禁能 CSC1 */
pxp_enable_csc1(0);
}
static void __app_blend (void)
{
uint8_t buf_index = 0U;
/*a pointer to a array*/
uint8_t (*p_vddr)[__APP_IMG_WIDTH * __APP_IMG_HEIGHT * __APP_BPP] = NULL;
int8_t ps_inc_x = 1;
int8_t ps_inc_y = 1;
int8_t as_inc_x = -1;
int8_t as_inc_y = -1;
uint16_t ps_ulc_x = 0U;
uint16_t ps_ulc_y = 0U;
uint16_t as_ulc_x = __APP_IMG_WIDTH - __APP_AS_WIDTH;
uint16_t as_ulc_y = __APP_IMG_HEIGHT - __APP_AS_HEIGHT;
uint16_t ps_lrc_x, ps_lrc_y, as_lrc_x, as_lrc_y;
ps_lrc_x = ps_ulc_x + __APP_PS_WIDTH - 1U;
ps_lrc_y = ps_ulc_y + __APP_PS_HEIGHT - 1U;
as_lrc_x = as_ulc_x + __APP_AS_WIDTH - 1U;
as_lrc_y = as_ulc_y + __APP_AS_HEIGHT - 1U;
p_vddr = (void *)__fix_screen_info.vram_addr;
while (1) {
/*将buffer放入缓存中*/
aw_cache_flush((void *)__gp_ps_buf, __APP_PS_HEIGHT * __APP_PS_WIDTH * __APP_BPP);
aw_cache_flush((void *)__gp_as_buf, __APP_AS_HEIGHT * __APP_AS_WIDTH * __APP_BPP);
/*PS图形位置*/
pxp_set_process_surface_position(ps_ulc_x, ps_ulc_y, ps_lrc_x, ps_lrc_y);
/*AS图形位置*/
pxp_set_alpha_surface_position(as_ulc_x, as_ulc_y, as_lrc_x, as_lrc_y);
/*配置输出buffer的显存地址*/
__g_output_buffer_config.buffer0_addr = (uint32_t)p_vddr[buf_index];
pxp_set_output_buffer_config(&__g_output_buffer_config);
/* Start PXP. */
pxp_start();
/* 等待PXP图形处理完成 */
pxp_complete_status_sync();
/*清空缓存中的buffer*/
aw_cache_invalidate((void *)__gp_ps_buf, __APP_PS_HEIGHT * __APP_PS_WIDTH * __APP_BPP);
aw_cache_invalidate((void *)__gp_as_buf, __APP_AS_HEIGHT * __APP_AS_WIDTH * __APP_BPP);
aw_cache_flush(
(void*)p_vddr[buf_index],
__var_info.buffer.buffer_size * __var_info.buffer.buffer_num);
/*切换显存*/
buf_index++;
if (buf_index >= __var_info.buffer.buffer_num) {
buf_index = 0;
}
ps_lrc_x += ps_inc_x;
ps_lrc_y += ps_inc_y;
as_lrc_x += as_inc_x;
as_lrc_y += as_inc_y;
ps_ulc_x += ps_inc_x;
ps_ulc_y += ps_inc_y;
as_ulc_x += as_inc_x;
as_ulc_y += as_inc_y;
if (0 == as_ulc_x) {
as_inc_x = 1;
} else if (__APP_IMG_WIDTH - 1 == as_lrc_x) {
as_inc_x = -1;
}
if (0 == as_ulc_y) {
as_inc_y = 1;
} else if (__APP_IMG_HEIGHT - 1 == as_lrc_y) {
as_inc_y = -1;
}
if (0 == ps_ulc_x) {
ps_inc_x = 1;
} else if (__APP_IMG_WIDTH - 1 == ps_lrc_x) {
ps_inc_x = -1;
}
if (0 == ps_ulc_y) {
ps_inc_y = 1;
} else if (__APP_IMG_HEIGHT - 1 == ps_lrc_y) {
ps_inc_y = -1;
}
aw_mdelay(50);
}
}
void demo_pxp_blend (void)
{
/* 初始化fram buffer */
aw_err_t ret = __fb_init();
if(ret != AW_OK){
aw_kprintf("fb init fail.\r\n");
return;
}
extern void lt9211_init();
lt9211_init();
__gp_ps_buf = (uint8_t *) aw_mem_align(__APP_PS_WIDTH * __APP_PS_HEIGHT * __APP_BPP,
AW_CACHE_LINE_SIZE);
__gp_as_buf = (uint8_t *) aw_mem_align(__APP_AS_WIDTH * __APP_AS_HEIGHT * __APP_BPP,
AW_CACHE_LINE_SIZE);
if (NULL == __gp_ps_buf || __gp_as_buf == NULL) {
aw_kprintf("aw_mem_align error.\r\n");
return ;
}
/* 初始化buffer */
__as_ps_buf_init();
/* 配置pxp */
__app_pxp_config();
/* blend测试 */
__app_blend();
aw_mem_free(__gp_ps_buf);
aw_mem_free(__gp_as_buf);
}
/* end of file */