基于安凯3760E的SDK-02

LVGL 显示设备适配

在main函数中我们调用了lv_port_disp_init(),此处分析其接口函数;

源码分析

static void disp_init(void)
{
	/*
	*初始化anyka3760e sdk
	*/
	sdk_run_config config = {0};
    config.mem_trace_flag = SDK_RUN_NORMAL;
    ak_sdk_init(&config);

	/*安装fb*/	
	system("insmod /usr/modules/ak_fb.ko");
	/*安装tde*/
	system("insmod /usr/modules/ak_gui.ko");
	
    /*You code here*/
	fbfd = open(FBDEV_PATH, O_RDWR|O_EXCL);
    if(fbfd == -1) 
	{
        perror("Error: cannot open framebuffer device");
        return;
    }

	if(ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1)
	{
        perror("Error reading fixed information");
        return;
    }

    // Get variable screen information
    if(ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1)
	{
        perror("Error reading variable information");
        return;
    }


	vinfo.xres = LV_HOR_RES_MAX;
    vinfo.yres = LV_VER_RES_MAX;
#ifdef LCD_FORMAT_24
	vinfo.bits_per_pixel = 24;
    vinfo.red.offset = 16;
    vinfo.red.length = 8 ;
    vinfo.green.offset = 8;
    vinfo.green.length = 8 ;
    vinfo.blue.offset = 0;
    vinfo.blue.length = 8;

#else
    vinfo.bits_per_pixel = 16;
    vinfo.red.offset = 11;
    vinfo.red.length = 5 ;
    vinfo.green.offset = 5;
    vinfo.green.length = 6 ;
    vinfo.blue.offset = 0;
    vinfo.blue.length = 5 ;
#endif
    ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo);


	int bpp = vinfo.bits_per_pixel;
	screensize = vinfo.xres*vinfo.yres*bpp/8;
	
	extern void *osal_fb_mmap_viraddr(int fb_len, int fb_fd);
	fbp = (unsigned char*)osal_fb_mmap_viraddr(screensize*2,fbfd);

	
	FB_BUFFER = FB_BUFFER_A;
	FB_BUFFER_SET;	

	fbp_phyaddres = finfo.smem_start;


	printf("fb buffer 1:%p,2:%p ,phy:%lu ,2:%lu \n",fbp,fbp + screensize,fbp_phyaddres,fbp_phyaddres + screensize);
	
	gui_buffer = (unsigned char*)ak_mem_dma_alloc(MODULE_ID_VO, LV_HOR_RES_MAX*LV_VER_RES_MAX*4);
	ak_mem_dma_vaddr2paddr(gui_buffer, (unsigned long *)&gui_phyaddres);
	
	ak_tde_open();
    printf("The framebuffer device was mapped to memory successfully.\n");
	
}

void lv_port_disp_init(void)
{
	/*初始化fb设备*/
    disp_init();

	/*
	*用一个屏幕大小(argb8888)的内存块用于lvgl内部画图
	* 
	*/
    static lv_disp_buf_t draw_buf_dsc_3;
	lv_color_t* draw_buf1 = (lv_color_t*)ak_mem_alloc(MODULE_ID_VO, LV_HOR_RES_MAX*LV_VER_RES_MAX*4);
    lv_disp_buf_init(&draw_buf_dsc_3,draw_buf1, NULL, LV_HOR_RES_MAX*LV_VER_RES_MAX);  

	/*
	*初始化显示设备
	*/
    lv_disp_drv_t disp_drv;                       
    lv_disp_drv_init(&disp_drv);                   

    disp_drv.hor_res = LV_HOR_RES_MAX;
    disp_drv.ver_res = LV_VER_RES_MAX;
	
	/*
	* 注册显示设备回调函数,在lvgl将控件准备好后通知此函数将画布填充到lcd上面
	*/
    disp_drv.flush_cb = disp_flush;

    /*Set a display buffer*/
    disp_drv.buffer = &draw_buf_dsc_3;

#if LV_USE_GPU
    disp_drv.gpu_blend_cb = gpu_blend;

    /*Fill a memory array with a color*/
    disp_drv.gpu_fill_cb = gpu_fill;
#endif
	/*
	* 真正将显示服务注册到lvgl内核中
	*/
    lv_disp_drv_register(&disp_drv);
}



static void fb_flush_to_fb(void)
{	
	FB_BUFFER_GET;
	FB_BUFFER = FB_BUFFER == FB_BUFFER_A?FB_BUFFER_B:FB_BUFFER_A;
	if((system_bg_enable == true)&&(system_bg_addres != NULL))
	{
		bg_flush_to_fb();
	}
	gui_flush_to_fb();
	FB_BUFFER_SET;
}

static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
	if(color_p == NULL)
	{
		goto pos_flush;
	}

	if(area->x2 < 0 ||area->y2 < 0 || area->x1 > (int32_t)vinfo.xres - 1 ||area->y1 > (int32_t)vinfo.yres - 1)
	{
        lv_disp_flush_ready(disp_drv);
        return;
    }

    int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
    int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;

    lv_coord_t src_w = lv_area_get_width(area);
	lv_coord_t src_h = lv_area_get_height(area);

	
	int disp_row_byte = LV_HOR_RES_MAX*4;
	int draw_row_byte = src_w*4; 
	unsigned char* dst = gui_buffer + act_y1*disp_row_byte + act_x1*4;
	unsigned char* src = (unsigned char*)color_p;
	for(int h = 0 ;  h < src_h ; h++)
	{
		memcpy(dst,src,draw_row_byte);
		dst += disp_row_byte;
		src += draw_row_byte;
	}
	if(lv_disp_flush_is_last(disp_drv) == true)
	{
pos_flush:
		fb_flush_to_fb();
		ak_sleep_ms(1);
		
	}
    lv_disp_flush_ready(disp_drv);
}

#endif

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值