您尚未登录。

楼主 # 2022-05-27 15:25:18

david
会员
注册时间: 2018-03-05
已发帖子: 357
积分: 297.5

F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

本以为RGB565的时候每个像素2字节?不过初步设置后如果按照2字节分配FB,只有一半显示,而且显示的还是4字节每像素的样子,例如memset设置成0x80显示的是灰色。

用的这款源码 https://github.com/vvhh2002/lv7_rtthread_f1c100s.git

小改 使用#define LCD_FORMAT  RTGRAPHIC_PIXEL_FORMAT_RGB565P而已

相关寄存器设置部分是这样

	if(dev->lcd_info.bits_per_pixel == 24 || dev->lcd_info.bits_per_pixel == 16 || dev->lcd_info.bits_per_pixel == 32)
	{
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[0],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[1],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[2],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[3],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[4],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[5],  0x11111111);

		write32((rt_uint32_t)&tcon->tcon0_frm_table[0], 0x01010000);
		write32((rt_uint32_t)&tcon->tcon0_frm_table[1], 0x15151111);
		write32((rt_uint32_t)&tcon->tcon0_frm_table[2], 0x57575555);
		write32((rt_uint32_t)&tcon->tcon0_frm_table[3], 0x7f7f7777);
        // 最高支持18位
		write32((rt_uint32_t)&tcon->tcon0_frm_ctrl, (dev->lcd_info.bits_per_pixel == 24 || dev->lcd_info.bits_per_pixel == 32) ? ((1 << 31) | (0 << 4)) : ((1 << 31) | (5 << 4)));
	}

还有

/**
 * @brief 设置DEBE模式(DEBE控制显示尺寸和显示缓冲地址)
 *
 * @param dev 设备指针
 */
static inline void f1c100s_debe_set_mode(struct lcd_f1c100s_device *dev)
{
	struct f1c100s_debe_reg_t * debe = (struct f1c100s_debe_reg_t *)(dev->virtdebe);
	rt_uint32_t val;

	val = read32((rt_uint32_t)&debe->mode);
	val |= (1 << 0);
	write32((rt_uint32_t)&debe->mode, val);

	write32((rt_uint32_t)&debe->disp_size, (((dev->lcd_info.height) - 1) << 16) | (((dev->lcd_info.width) - 1) << 0));
	write32((rt_uint32_t)&debe->layer0_size, (((dev->lcd_info.height) - 1) << 16) | (((dev->lcd_info.width) - 1) << 0));
	write32((rt_uint32_t)&debe->layer0_stride, ((dev->lcd_info.width) << 5));
	write32((rt_uint32_t)&debe->layer0_addr_low32b, (uint32_t)(dev->lcd_info.framebuffer) << 3);
	write32((rt_uint32_t)&debe->layer0_addr_high4b, (uint32_t)(dev->lcd_info.framebuffer) >> 29);
	//write32((rt_uint32_t)&debe->layer0_attr1_ctrl, 0x09 << 8);
    write32((rt_uint32_t)&debe->layer0_attr1_ctrl, (0x09 << 8)|(1<<2));
	//write32((rt_uint32_t)&debe->layer0_attr1_ctrl, 0x0A << 8);
	val = read32((rt_uint32_t)&debe->mode);
	val |= (1 << 8);
	write32((rt_uint32_t)&debe->mode, val);

	val = read32((rt_uint32_t)&debe->reg_ctrl);
	val |= (1 << 0);
	write32((rt_uint32_t)&debe->reg_ctrl, val);

	val = read32((rt_uint32_t)&debe->mode);
	val |= (1 << 1);
	write32((rt_uint32_t)&debe->mode, val);
}

以上都是大神原来的代码,我没改动。

感觉是不是RGB565的哪个寄存器没设置到位?要是RGB565用不了2字节每像素的话就没有意义了。

离线

楼主 #1 2022-05-27 15:30:01

david
会员
注册时间: 2018-03-05
已发帖子: 357
积分: 297.5

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

另外 看手册5.1.5.4 TCON FRM Control Register的设置,LCD显示是不是最多支持到RGB666,那个RGB888实际上就是RGB666?

离线

#2 2022-05-27 16:22:14

xfdr0805
会员
注册时间: 2020-07-23
已发帖子: 291
积分: 344

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

也碰到了这个问题 不过我用的uboot 改为RGB565 屏幕就显示一半 而且这一半又分了左右2个

离线

楼主 #3 2022-05-29 16:43:15

david
会员
注册时间: 2018-03-05
已发帖子: 357
积分: 297.5

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

这个问题解决了 要在tcon和debe里配合设置。

离线

楼主 #4 2022-05-29 16:45:15

david
会员
注册时间: 2018-03-05
已发帖子: 357
积分: 297.5

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

而且我参考的那份代码存在bug 它在preprocessor里引用了enum的定义

离线

#5 2022-05-29 20:59:24

xfdr0805
会员
注册时间: 2020-07-23
已发帖子: 291
积分: 344

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

david 说:

这个问题解决了 要在tcon和debe里配合设置。

楼主,能分享一下 uboot fb  如何修改为16位吗

离线

楼主 #6 2022-05-29 21:49:12

david
会员
注册时间: 2018-03-05
已发帖子: 357
积分: 297.5

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

这两块代码供参考

inline static void f1c100s_debe_set_address(struct lcd_f1c100s_device *dev)
{
	struct f1c100s_debe_reg_t * debe = (struct f1c100s_debe_reg_t *)(dev->virtdebe);

	write32((rt_uint32_t)&debe->layer0_addr_low32b, (uint32_t)(dev->lcd_info.framebuffer[fb_bank? 1:0]) << 3); // address in bits 3->8bit(byte address)
	write32((rt_uint32_t)&debe->layer0_addr_high4b, (uint32_t)(dev->lcd_info.framebuffer[fb_bank? 1:0]) >> 29);

	//write32((rt_uint32_t)&debe->layer0_addr_low32b, (uint32_t)vram << 3);
	//write32((rt_uint32_t)&debe->layer0_addr_high4b, (uint32_t)vram >> 29);
}

static inline void f1c100s_debe_set_mode(struct lcd_f1c100s_device *dev)
{
	struct f1c100s_debe_reg_t * debe = (struct f1c100s_debe_reg_t *)(dev->virtdebe);
	rt_uint32_t val;
	rt_uint32_t mode_val;
    
    // enable debe, layer0 but set the reset
    mode_val = (1<<8) | (1<<0);
	write32((rt_uint32_t)&debe->mode, mode_val);

	write32((rt_uint32_t)&debe->disp_size, (((dev->lcd_info.height) - 1) << 16) | (((dev->lcd_info.width) - 1) << 0));
	write32((rt_uint32_t)&debe->layer0_size, (((dev->lcd_info.height) - 1) << 16) | (((dev->lcd_info.width) - 1) << 0));
    
    f1c100s_debe_set_address(dev);
	//write32((rt_uint32_t)&debe->layer0_addr_low32b, (uint32_t)(dev->lcd_info.framebuffer) << 3); // address in bits 3->8bit(byte address)
	//write32((rt_uint32_t)&debe->layer0_addr_high4b, (uint32_t)(dev->lcd_info.framebuffer) >> 29);
    
    //val = (1<<2); // swap B R, i.e. BGR
    val = 0;
    if (dev->lcd_info.bits_per_pixel == 16)
    {
        val |= (0x05 << 8);
        write32((rt_uint32_t)&debe->layer0_stride, ((dev->lcd_info.width) << 4)); // line width in bits 5->32bit, 4->16bit
    }
    else // FIXME: default 32bit RGB
    {
        val |= (0x09 << 8);
        write32((rt_uint32_t)&debe->layer0_stride, ((dev->lcd_info.width) << 5)); // line width in bits 5->32bit, 4->16bit
    }
    write32((rt_uint32_t)&debe->layer0_attr1_ctrl, val);

    // start debe
    mode_val |= (1 << 1);
	write32((rt_uint32_t)&debe->mode, mode_val);
}
static inline void f1c100s_tcon_set_mode(struct lcd_f1c100s_device *dev)
{
	struct f1c100s_tcon_reg_t * tcon = (struct f1c100s_tcon_reg_t *)dev->virttcon;
	int bp, total;
	rt_uint32_t val;

	val = read32((rt_uint32_t)&tcon->ctrl);
	val &= ~(0x1 << 0);
	write32((rt_uint32_t)&tcon->ctrl, val);

	val = (dev->timing.v_front_porch + dev->timing.v_back_porch + dev->timing.v_sync_len);
	write32((rt_uint32_t)&tcon->tcon0_ctrl, (1 << 31) | ((val & 0x1f) << 4));
	// val = clk_get_rate(dev->clktcon) / dev->timing.pixel_clock_hz;
    // rt_kprintf("get_video_pll_clk:%d\n", get_video_pll_clk());
    val = get_video_pll_clk() / dev->timing.pixel_clock_hz;
	write32((rt_uint32_t)&tcon->tcon0_dclk, (0xf << 28) | (val << 0));
	write32((rt_uint32_t)&tcon->tcon0_timing_active, ((dev->lcd_info.width - 1) << 16) | ((dev->lcd_info.height - 1) << 0));

	bp = dev->timing.h_sync_len + dev->timing.h_back_porch;
	total = dev->lcd_info.width + dev->timing.h_front_porch + bp;
	write32((rt_uint32_t)&tcon->tcon0_timing_h, ((total - 1) << 16) | ((bp - 1) << 0));
	bp = dev->timing.v_sync_len + dev->timing.v_back_porch;
	total = dev->lcd_info.height + dev->timing.v_front_porch + bp;
	write32((rt_uint32_t)&tcon->tcon0_timing_v, ((total * 2) << 16) | ((bp - 1) << 0));
	write32((rt_uint32_t)&tcon->tcon0_timing_sync, ((dev->timing.h_sync_len - 1) << 16) | ((dev->timing.v_sync_len - 1) << 0));

	write32((rt_uint32_t)&tcon->tcon0_hv_intf, 0);
	write32((rt_uint32_t)&tcon->tcon0_cpu_intf, 0);

	if(dev->lcd_info.bits_per_pixel == 24 || dev->lcd_info.bits_per_pixel == 16 || dev->lcd_info.bits_per_pixel == 32)
	{
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[0],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[1],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[2],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[3],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[4],  0x11111111);
		write32((rt_uint32_t)&tcon->tcon0_frm_seed[5],  0x11111111);

		write32((rt_uint32_t)&tcon->tcon0_frm_table[0], 0x01010000);
		write32((rt_uint32_t)&tcon->tcon0_frm_table[1], 0x15151111);
		write32((rt_uint32_t)&tcon->tcon0_frm_table[2], 0x57575555);
		write32((rt_uint32_t)&tcon->tcon0_frm_table[3], 0x7f7f7777);
        // 最高支持18位
		write32((rt_uint32_t)&tcon->tcon0_frm_ctrl, (dev->lcd_info.bits_per_pixel == 24 || dev->lcd_info.bits_per_pixel == 32) ? ((1 << 31) | (0 << 4)) : ((1 << 31) | (5 << 4)));
	}

	val = (1 << 28);
	if(!dev->timing.h_sync_active)
		val |= (1 << 25);
	if(!dev->timing.v_sync_active)
		val |= (1 << 24);
	if(!dev->timing.den_active)
		val |= (1 << 27);
	if(!dev->timing.clk_active)
		val |= (1 << 26);
	write32((rt_uint32_t)&tcon->tcon0_io_polarity, val);
	write32((rt_uint32_t)&tcon->tcon0_io_tristate, 0);
}

离线

#7 2022-06-15 18:14:57

xfdr0805
会员
注册时间: 2020-07-23
已发帖子: 291
积分: 344

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

感谢楼主提供的代码参考,已经搞定

离线

#8 2023-10-11 11:10:57

overtree
会员
注册时间: 2023-09-24
已发帖子: 3
积分: 3

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

xfdr0805 说:

感谢楼主提供的代码参考,已经搞定

楼主可以共享一下你修改后的代码吗?我也修改了,虽然不会显示一半,但是颜色失真了。

离线

#9 2023-10-11 21:38:07

overtree
会员
注册时间: 2023-09-24
已发帖子: 3
积分: 3

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

overtree 说:
xfdr0805 说:

感谢楼主提供的代码参考,已经搞定

楼主可以共享一下你修改后的代码吗?我也修改了,虽然不会显示一半,但是颜色失真了。

已解决,需要自己将 RGBA888 的颜色转为 RGB565

离线

#10 2023-10-12 17:19:26

wenjiu
会员
注册时间: 2023-10-12
已发帖子: 6
积分: 1

Re: F1c100s RGB565的时候frame buffer是不是还要4个字节每个像素?

使用LVGL,flush_cb中要等什么信号吗?

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn