本以为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字节每像素的话就没有意义了。
离线
另外 看手册5.1.5.4 TCON FRM Control Register的设置,LCD显示是不是最多支持到RGB666,那个RGB888实际上就是RGB666?
离线
也碰到了这个问题 不过我用的uboot 改为RGB565 屏幕就显示一半 而且这一半又分了左右2个
离线
这个问题解决了 要在tcon和debe里配合设置。
离线
而且我参考的那份代码存在bug 它在preprocessor里引用了enum的定义
离线
这个问题解决了 要在tcon和debe里配合设置。
楼主,能分享一下 uboot fb 如何修改为16位吗
离线
这两块代码供参考
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);
}
离线
感谢楼主提供的代码参考,已经搞定
离线
感谢楼主提供的代码参考,已经搞定
楼主可以共享一下你修改后的代码吗?我也修改了,虽然不会显示一半,但是颜色失真了。
离线
xfdr0805 说:感谢楼主提供的代码参考,已经搞定
楼主可以共享一下你修改后的代码吗?我也修改了,虽然不会显示一半,但是颜色失真了。
已解决,需要自己将 RGBA888 的颜色转为 RGB565
离线
使用LVGL,flush_cb中要等什么信号吗?
离线