看到荔枝派Nano的LCD接口是RGB接口的。F1C100s手册里说TCON支持也MCU(i8080)接口,但是引脚只有适合RGB接口的HSYNC/VSYNC/DE,没有MCU屏的RD/WR。所以MCU接口的屏要怎么接呢?
似乎小尺寸的屏RGB接口的不多。
离线
可以接 i80 接口的 mcu 屏,bsp linux ,melis ,xboot 都支持这种屏
离线
引脚如何接呢?WR/RD对应于RGB屏的哪个引脚?
离线
谢谢,明白了!做个板子试一下。
按照彩虹派的接法,SoC引脚到MCU屏的接法如下:
LCD_CLK -- 33Ω电阻 -- WR
LCD_DE -- RS
LCD_HSYNC -- RD
最近编辑记录 Quotation (2019-03-18 00:40:10)
离线
晕哥 说:谢谢,明白了!做个板子试一下。
按照彩虹派的接法,SoC引脚到MCU屏的接法如下:
LCD_CLK -- 33Ω电阻 -- WR
LCD_DE -- RS
LCD_HSYNC -- RD
坐等调通 I80 LCD 好消息
离线
按晕哥的提示,参考了 彩虹派V3s开发板原理图 和 A10 LCD 调试手册 这两份资料,画了块RGB屏转 i80屏的转接板。等打样回来慢慢调~
(图上丝印1脚和常用的线序是反的)
最近编辑记录 Quotation (2019-03-18 17:45:43)
离线
楼主 进度如何 我也想驱动一个i80接口的屏幕
离线
按晕哥的提示,参考了 彩虹派V3s开发板原理图 和 A10 LCD 调试手册 这两份资料,画了块RGB屏转 i80屏的转接板。等打样回来慢慢调~
(图上丝印1脚和常用的线序是反的)
后面成功了吗?原理图是否正确?
离线
直接IO模拟可以吗
离线
直接IO模拟可以吗
据说司徒的 miyoo 就是用 IO 直接驱动 I80 液晶的:
https://github.com/qq516333132/f1c500s_kernel
xboot 有 i80 的驱动代码:
https://github.com/xboot/xboot/blob/master/src/arch/arm32/mach-f1c500s/driver/fb-f1c500s.c
static inline void fb_f1c500s_init(struct fb_f1c500s_pdata_t * pdat)
{
fb_f1c500s_cfg_gpios(F1C500S_GPIOD1, 8, 0x1, GPIO_PULL_NONE, GPIO_DRV_STRONG);
fb_f1c500s_cfg_gpios(F1C500S_GPIOD10, 12, 0x1, GPIO_PULL_NONE, GPIO_DRV_STRONG);
r61520_init(pdat);
fb_f1c500s_cfg_gpios(F1C500S_GPIOD1, 8, 0x2, GPIO_PULL_NONE, GPIO_DRV_STRONG);
fb_f1c500s_cfg_gpios(F1C500S_GPIOD10, 12, 0x2, GPIO_PULL_NONE, GPIO_DRV_STRONG);
f1c500s_tcon_disable(pdat);
f1c500s_debe_set_mode(pdat);
f1c500s_tcon_set_mode(pdat);
f1c500s_tcon_enable(pdat);
}
离线
i80也有18/16/9/9bit不同接法啊。
miyoo是i80 16bit接法,好像rgb565吧
离线
xboot 有 i80 的驱动代码:
https://github.com/xboot/xboot/blob/master/src/arch/arm32/mach-f1c500s/driver/fb-f1c500s.cstatic inline void fb_f1c500s_init(struct fb_f1c500s_pdata_t * pdat) { fb_f1c500s_cfg_gpios(F1C500S_GPIOD1, 8, 0x1, GPIO_PULL_NONE, GPIO_DRV_STRONG); fb_f1c500s_cfg_gpios(F1C500S_GPIOD10, 12, 0x1, GPIO_PULL_NONE, GPIO_DRV_STRONG); r61520_init(pdat); fb_f1c500s_cfg_gpios(F1C500S_GPIOD1, 8, 0x2, GPIO_PULL_NONE, GPIO_DRV_STRONG); fb_f1c500s_cfg_gpios(F1C500S_GPIOD10, 12, 0x2, GPIO_PULL_NONE, GPIO_DRV_STRONG); f1c500s_tcon_disable(pdat); f1c500s_debe_set_mode(pdat); f1c500s_tcon_set_mode(pdat); f1c500s_tcon_enable(pdat); }
is it easy to port to linux?
I have to use i80 with f1c100s.
what would be right step to bring i80 to linux any suggestion ?
离线
按晕哥的提示,参考了 彩虹派V3s开发板原理图 和 A10 LCD 调试手册 这两份资料,画了块RGB屏转 i80屏的转接板。等打样回来慢慢调~
(图上丝印1脚和常用的线序是反的)
板子画的不错,祝早日调通。
离线
早日调通,我也想了解一下MCU的屏。
离线
题主有结果了吗?可以肯定IO模拟8080接口是没问题,但效率就有些差强人意了,但rgb也是ttl电平,我觉得应该也是可以驱动8080接口,但怎么驱动没有头绪
离线
不知道楼主驱动8080屏成功了没,感谢分享
离线
可以接MCU 8位,16位的屏
离线
不行的话,可以使用GPIO模拟
离线
想知道楼主驱动8080屏成功了没,毕竟小屏大部分都是8080接口,同时感谢分享,
离线
请问现在结果如何了
离线
请问楼主最近也想驱动8080接口的屏。请问你驱动了吗?
离线
查阅大量资料花了好几天有点头绪了,分享一下/*MCU手册写TCON Register List
Module Name Base Address
TCON 0x01C0C000
代码中定义#define SUNXI_LCD0_BASE 0x01c0C000
则lcdc指针就是指向TCON寄存器*/,然后我查看手册5.1.4. TCON Register List
Module Name Base Address
TCON 0x01C0C000
Register Name Offset Description
TCON_CTRL_REG 0x000 TCON Control Register
TCON_INT_REG0 0x004 TCON Interrupt Register 0
TCON_INT_REG1 0x008 TCON Interrupt Register 1
TCON_FRM_CTRL_REG 0x010 TCON FRM Control Register
TCON_FRM_SEED0_R_REG 0x014 TCON FRM Seed0 Red Register
TCON_FRM_SEED0_G_REG 0x018 TCON FRM Seed0 Green Register
TCON_FRM_SEED0_B_REG 0x01C TCON FRM Seed0 Blue Register
TCON_FRM_SEED1_R_REG 0x020 TCON FRM Seed1 Red Register
TCON_FRM_SEED1_G_REG 0x024 TCON FRM Seed1 Green Register
TCON_FRM_SEED1_B_REG 0x028 TCON FRM Seed1 Blue Register
TCON_FRM_TBL_REG0 0x02C TCON FRM Table Register 0
TCON_FRM_TBL_REG1 0x030 TCON FRM Table Register 1
TCON_FRM_TBL_REG2 0x034 TCON FRM Table Register 2
TCON_FRM_TBL_REG3 0x038 TCON FRM Table Register 3
TCON0_CTRL_REG 0x040 TCON0 Control Register
TCON_CLK_CTRL_REG 0x044 TCON Clock Control Register
TCON0_BASIC_TIMING_REG0 0x048 TCON0 Basic Timing Register 0
TCON0_BASIC_TIMING _REG1 0x04C TCON0 Basic Timing Register 1
TCON0_BASIC_TIMING _REG2 0x050 TCON0 Basic Timing Register 2
TCON0_BASIC_TIMING _REG3 0x054 TCON0 Basic Timing Register 3
TCON0_HV_TIMING_REG 0x058 TCON0 HV Timing Register
TCON0_ CPU_IF_REG 0X060 TCON0 CPU Interface Control Register
TCON0_CPU_WR_REG 0x064 TCON0 CPU Mode Write Register
TCON0_CPU_RD_REG 0x068 TCON0 CPU Mode Read Register
TCON0_CPU_RD_NX_REG 0x06C TCON0 CPU Mode Read NX Register
TCON0_IO_CTRL_REG0 0x088 TCON0 IO Control Register 0
TCON0_IO_CTRL_REG1 0x08C TCON0 IO Control Register 1
TCON1_CTRL_REG 0x090 TCON1 Control Register
TCON1_BASIC_REG0 0x094 TCON1 Basic Timing Register 0
TCON1_BASIC_REG1 0x098 TCON1 Basic Timing Register 1
TCON1_BASIC_REG2 0x09C TCON1 Basic Timing Register 2
TCON1_BASIC_REG3 0x0A0 TCON1 Basic Timing Register 3
TCON1_BASIC_REG4 0x0A4 TCON1 Basic Timing Register 4
TCON1_BASIC_REG5 0x0A8 TCON1 Basic Timing Register 5
TCON1_IO_CTRL_REG0 0x0F0 TCON1 IO Control Register 0
TCON1_IO_CTRL_REG1 0x0F4 TCON1 IO Control Register 1
TCON_DEBUG_INFO_REG 0x0FC TCON Debug Information Register
For Allwinner Tech Ent,我又去源码查看/*MCU手册写TCON Register List
Module Name Base Address
TCON 0x01C0C000
代码中定义#define SUNXI_LCD0_BASE 0x01c0C000
则lcdc指针就是指向TCON寄存器*/
static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode,
bool for_ext_vga_dac)
{
struct sunxi_lcdc_reg * const lcdc =
(struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE;
struct sunxi_ccm_reg * const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
int clk_div, clk_double, pin;
struct display_timing timing;
#if defined CONFIG_MACH_SUN8I && defined CONFIG_VIDEO_LCD_IF_LVDS
for (pin = SUNXI_GPD(18); pin <= SUNXI_GPD(27); pin++) {
#else
for (pin = SUNXI_GPD(0); pin <= SUNXI_GPD(27); pin++) {
#endif
#ifdef CONFIG_VIDEO_LCD_IF_PARALLEL
sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LCD0);
#endif
#ifdef CONFIG_VIDEO_LCD_IF_LVDS
sunxi_gpio_set_cfgpin(pin, SUNXI_GPD_LVDS0);
#endif
#ifdef CONFIG_VIDEO_LCD_PANEL_EDP_4_LANE_1620M_VIA_ANX9804
sunxi_gpio_set_drv(pin, 3);
#endif
}
lcdc_pll_set(ccm, 0, mode->pixclock_khz, &clk_div, &clk_double,
sunxi_is_composite());
sunxi_ctfb_mode_to_display_timing(mode, &timing);
lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac,
sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE);
}调用了lcdc_tcon0_mode_set(lcdc, &timing, clk_div, for_ext_vga_dac,
sunxi_display.depth, CONFIG_VIDEO_LCD_DCLK_PHASE);第一个参数就是TCONO的寄存器基地址0x01C0C000 ,那再看源码中struct sunxi_lcdc_reg {
u32 ctrl; /* 0x00 */
u32 int0; /* 0x04 */
u32 int1; /* 0x08 */
u8 res0[0x04]; /* 0x0c */
u32 tcon0_frm_ctrl; /* 0x10 */
u32 tcon0_frm_seed[6]; /* 0x14 */
u32 tcon0_frm_table[4]; /* 0x2c */
u8 res1[4]; /* 0x3c */
u32 tcon0_ctrl; /* 0x40 */
u32 tcon0_dclk; /* 0x44 */
u32 tcon0_timing_active; /* 0x48 */
u32 tcon0_timing_h; /* 0x4c */
u32 tcon0_timing_v; /* 0x50 */
u32 tcon0_timing_sync; /* 0x54 */
u32 tcon0_hv_intf; /* 0x58 */
u8 res2[0x04]; /* 0x5c */
u32 tcon0_cpu_intf; /* 0x60 */
u32 tcon0_cpu_wr_dat; /* 0x64 */
u32 tcon0_cpu_rd_dat0; /* 0x68 */
u32 tcon0_cpu_rd_dat1; /* 0x6c */
u32 tcon0_ttl_timing0; /* 0x70 */
u32 tcon0_ttl_timing1; /* 0x74 */
u32 tcon0_ttl_timing2; /* 0x78 */
u32 tcon0_ttl_timing3; /* 0x7c */
u32 tcon0_ttl_timing4; /* 0x80 */
u32 tcon0_lvds_intf; /* 0x84 */
u32 tcon0_io_polarity; /* 0x88 */
u32 tcon0_io_tristate; /* 0x8c */
u32 tcon1_ctrl; /* 0x90 */
u32 tcon1_timing_source; /* 0x94 */
u32 tcon1_timing_scale; /* 0x98 */
u32 tcon1_timing_out; /* 0x9c */
u32 tcon1_timing_h; /* 0xa0 */
u32 tcon1_timing_v; /* 0xa4 */
u32 tcon1_timing_sync; /* 0xa8 */
u8 res3[0x44]; /* 0xac */
u32 tcon1_io_polarity; /* 0xf0 */
u32 tcon1_io_tristate; /* 0xf4 */
u8 res4[0x108]; /* 0xf8 */
u32 mux_ctrl; /* 0x200 */
u8 res5[0x1c]; /* 0x204 */
u32 lvds_ana0; /* 0x220 */
u32 lvds_ana1; /* 0x224 */
};可以确认, u32 tcon0_ctrl; /* 0x40 */就是我们一直找的5.1.5.15. TCON0 Control Register
Offset: 0x040 Register Name: TCON0_CTRL_REG寄存器,再看源码void lcdc_tcon0_mode_set(struct sunxi_lcdc_reg * const lcdc,
const struct display_timing *mode,
int clk_div, bool for_ext_vga_dac,
int depth, int dclk_phase)
{
int bp, clk_delay, total, val;
#ifndef CONFIG_SUNXI_DE2
/* Use tcon0 */
clrsetbits_le32(&lcdc->ctrl, SUNXI_LCDC_CTRL_IO_MAP_MASK,
SUNXI_LCDC_CTRL_IO_MAP_TCON0);
#endif
clk_delay = lcdc_get_clk_delay(mode, 0);
writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);
writel(SUNXI_LCDC_TCON0_DCLK_ENABLE |
SUNXI_LCDC_TCON0_DCLK_DIV(clk_div), &lcdc->tcon0_dclk);
writel(SUNXI_LCDC_X(mode->hactive.typ) |
SUNXI_LCDC_Y(mode->vactive.typ), &lcdc->tcon0_timing_active);
bp = mode->hsync_len.typ + mode->hback_porch.typ;
total = mode->hactive.typ + mode->hfront_porch.typ + bp;
writel(SUNXI_LCDC_TCON0_TIMING_H_TOTAL(total) |
SUNXI_LCDC_TCON0_TIMING_H_BP(bp), &lcdc->tcon0_timing_h);
bp = mode->vsync_len.typ + mode->vback_porch.typ;
total = mode->vactive.typ + mode->vfront_porch.typ + bp;
writel(SUNXI_LCDC_TCON0_TIMING_V_TOTAL(total) |
SUNXI_LCDC_TCON0_TIMING_V_BP(bp), &lcdc->tcon0_timing_v);
#if defined(CONFIG_VIDEO_LCD_IF_PARALLEL) || defined(CONFIG_VIDEO_DE2)
writel(SUNXI_LCDC_X(mode->hsync_len.typ) |
SUNXI_LCDC_Y(mode->vsync_len.typ), &lcdc->tcon0_timing_sync);
writel(0, &lcdc->tcon0_hv_intf);
writel(0, &lcdc->tcon0_cpu_intf);
#endif
#ifdef CONFIG_VIDEO_LCD_IF_LVDS
val = (depth == 18) ? 1 : 0;
writel(SUNXI_LCDC_TCON0_LVDS_INTF_BITWIDTH(val) |
SUNXI_LCDC_TCON0_LVDS_CLK_SEL_TCON0, &lcdc->tcon0_lvds_intf);
#endif
if (depth == 18 || depth == 16) {
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[0]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[1]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[2]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[3]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[4]);
writel(SUNXI_LCDC_TCON0_FRM_SEED, &lcdc->tcon0_frm_seed[5]);
writel(SUNXI_LCDC_TCON0_FRM_TAB0, &lcdc->tcon0_frm_table[0]);
writel(SUNXI_LCDC_TCON0_FRM_TAB1, &lcdc->tcon0_frm_table[1]);
writel(SUNXI_LCDC_TCON0_FRM_TAB2, &lcdc->tcon0_frm_table[2]);
writel(SUNXI_LCDC_TCON0_FRM_TAB3, &lcdc->tcon0_frm_table[3]);
writel(((depth == 18) ?
SUNXI_LCDC_TCON0_FRM_CTRL_RGB666 :
SUNXI_LCDC_TCON0_FRM_CTRL_RGB565),
&lcdc->tcon0_frm_ctrl);
}
val = SUNXI_LCDC_TCON0_IO_POL_DCLK_PHASE(dclk_phase);
if (mode->flags & DISPLAY_FLAGS_HSYNC_LOW)
val |= SUNXI_LCDC_TCON_HSYNC_MASK;
if (mode->flags & DISPLAY_FLAGS_VSYNC_LOW)
val |= SUNXI_LCDC_TCON_VSYNC_MASK;
#ifdef CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH
if (for_ext_vga_dac)
val = 0;
#endif
writel(val, &lcdc->tcon0_io_polarity);
//把 TCON0 的所有 IO 从高阻态变为正常输出,这是“启用引脚”的最后一步。
writel(0, &lcdc->tcon0_io_tristate);
},只有此处writel(SUNXI_LCDC_TCON0_CTRL_ENABLE |
SUNXI_LCDC_TCON0_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon0_ctrl);设置TCON0开启和延时,那么lcdc->tcon0_ctrl的26:24 R/W 0 I/F: panel interface type select
00: HV(Sync+DE)
01: 8080 I/F
1x: reserved默认应该还是0,也就是 HV(Sync+DE),是通用40pin RGB LCD,可以改成I8080模式了
离线