Kaynağa Gözat

add:qspi-lcd接口支持和对应屏幕支持

alienwalker 1 yıl önce
ebeveyn
işleme
9b7ae3fd44

+ 20 - 7
components/lcd/luat_lcd.c

@@ -128,6 +128,7 @@ const char* luat_lcd_name(luat_lcd_conf_t* conf) {
 LUAT_WEAK int luat_lcd_init_default(luat_lcd_conf_t* conf) {
     uint8_t direction_date = 0;
 	conf->is_init_done = 0;
+
     if (conf->w == 0)
         conf->w = LCD_W;
     if (conf->h == 0)
@@ -141,6 +142,11 @@ LUAT_WEAK int luat_lcd_init_default(luat_lcd_conf_t* conf) {
 
     if (conf->pin_pwr != LUAT_GPIO_NONE)
         luat_gpio_set(conf->pin_pwr, Luat_GPIO_LOW);
+	if (conf->opts->user_ctrl_init)
+	{
+		conf->opts->user_ctrl_init(conf);
+		goto INIT_DONE;
+	}
     luat_gpio_set(conf->pin_rst, Luat_GPIO_LOW);
     luat_rtos_task_sleep(100);
     luat_gpio_set(conf->pin_rst, Luat_GPIO_HIGH);
@@ -165,7 +171,7 @@ LUAT_WEAK int luat_lcd_init_default(luat_lcd_conf_t* conf) {
     luat_lcd_clear(conf,LCD_BLACK);
     /* display on */
     luat_lcd_display_on(conf);
-
+INIT_DONE:
     conf->is_init_done = 1;
     for (size_t i = 0; i < LUAT_LCD_CONF_COUNT; i++){
         if (confs[i] == NULL) {
@@ -181,27 +187,27 @@ LUAT_WEAK int luat_lcd_init(luat_lcd_conf_t* conf) {
 }
 
 int luat_lcd_close(luat_lcd_conf_t* conf) {
-    if (conf->pin_pwr != 255)
+    if (conf->pin_pwr != LUAT_GPIO_NONE)
         luat_gpio_set(conf->pin_pwr, Luat_GPIO_LOW);
     return 0;
 }
 
 int luat_lcd_display_off(luat_lcd_conf_t* conf) {
-    if (conf->pin_pwr != 255)
+    if (conf->pin_pwr != LUAT_GPIO_NONE)
         luat_gpio_set(conf->pin_pwr, Luat_GPIO_LOW);
     lcd_write_cmd_data(conf,0x28, NULL, 0);
     return 0;
 }
 
 int luat_lcd_display_on(luat_lcd_conf_t* conf) {
-    if (conf->pin_pwr != 255)
+    if (conf->pin_pwr != LUAT_GPIO_NONE)
         luat_gpio_set(conf->pin_pwr, Luat_GPIO_HIGH);
     lcd_write_cmd_data(conf,0x29, NULL, 0);
     return 0;
 }
 
 int luat_lcd_sleep(luat_lcd_conf_t* conf) {
-    if (conf->pin_pwr != 255)
+    if (conf->pin_pwr != LUAT_GPIO_NONE)
         luat_gpio_set(conf->pin_pwr, Luat_GPIO_LOW);
     luat_rtos_task_sleep(5);
     lcd_write_cmd_data(conf,conf->opts->sleep_cmd?conf->opts->sleep_cmd:LUAT_LCD_DEFAULT_SLEEP, NULL, 0);
@@ -209,7 +215,7 @@ int luat_lcd_sleep(luat_lcd_conf_t* conf) {
 }
 
 int luat_lcd_wakeup(luat_lcd_conf_t* conf) {
-    if (conf->pin_pwr != 255)
+    if (conf->pin_pwr != LUAT_GPIO_NONE)
         luat_gpio_set(conf->pin_pwr, Luat_GPIO_HIGH);
     luat_rtos_task_sleep(5);
     lcd_write_cmd_data(conf,conf->opts->wakeup_cmd?conf->opts->wakeup_cmd:LUAT_LCD_DEFAULT_WAKEUP, NULL, 0);
@@ -264,7 +270,14 @@ int luat_lcd_flush_default(luat_lcd_conf_t* conf) {
     }
     if (conf->opts->lcd_draw) {
     	//LLOGD("luat_lcd_flush user flush");
-    	conf->opts->lcd_draw(conf, 0, conf->flush_y_min, conf->w - 1, conf->flush_y_max, &conf->buff[conf->flush_y_min * conf->w]);
+    	if (conf->opts->no_ram_mode)
+    	{
+    		conf->opts->lcd_draw(conf, 0, 0, 0, 0, conf->buff);
+    	}
+    	else
+    	{
+    		conf->opts->lcd_draw(conf, 0, conf->flush_y_min, conf->w - 1, conf->flush_y_max, &conf->buff[conf->flush_y_min * conf->w]);
+    	}
     } else {
         uint32_t size = conf->w * (conf->flush_y_max - conf->flush_y_min + 1) * 2;
         luat_lcd_set_address(conf, 0, conf->flush_y_min, conf->w - 1, conf->flush_y_max);

+ 23 - 3
components/lcd/luat_lcd.h

@@ -49,14 +49,24 @@ enum{
 	LUAT_LCD_IM_3_WIRE_9_BIT_INTERFACE_II = 13,
 	LUAT_LCD_IM_4_WIRE_8_BIT_INTERFACE_II = 14,
 	LUAT_LCD_IM_2_DATA_LANE = 16,
+	LUAT_LCD_IM_QSPI_MODE = 0x20,
+	LUAT_LCD_IM_8080_MODE = 0x30,
 };
 
+typedef struct
+{
+	uint8_t write_4line_cmd;
+	uint8_t vsync_reg;
+	uint8_t hsync_cmd;
+	uint8_t hsync_reg;
+	uint8_t write_1line_cmd;
+}luat_lcd_qspi_conf_t;
+
 typedef struct luat_lcd_conf {
     uint8_t port;
     uint8_t pin_dc;
     uint8_t pin_pwr;
     uint8_t pin_rst;
-
     int16_t w;
     int16_t h;
     uint32_t buffer_size;
@@ -77,9 +87,14 @@ typedef struct luat_lcd_conf {
     int16_t flush_y_min;
     int16_t flush_y_max;
     uint8_t is_init_done;
-
     uint8_t interface_mode;	// LUAT_LCD_IM_XXX
     uint8_t lcd_cs_pin;		//注意不用的时候写0xff
+    uint8_t bpp;			//颜色bit,默认是RGB565 16bit,预留兼容ARGB888 32bit
+    uint32_t flush_rate;	//刷新率,针对no ram的屏幕起效
+    uint32_t bus_speed;
+    uint16_t vfp;
+    uint16_t vbp;
+    uint16_t vs;
 } luat_lcd_conf_t;
 
 typedef struct luat_lcd_opts {
@@ -91,9 +106,10 @@ typedef struct luat_lcd_opts {
     uint8_t direction180;
     uint8_t direction270;
     uint8_t rb_swap;
-    uint8_t unused;
+    uint8_t no_ram_mode;
     uint16_t init_cmds_len;
     uint16_t* init_cmds;
+    int (*user_ctrl_init)(luat_lcd_conf_t* conf);
     int (*init)(luat_lcd_conf_t* conf);
     int (*write_cmd_data)(luat_lcd_conf_t* conf,const uint8_t cmd, const uint8_t *data, uint8_t data_len);
     int (*read_cmd_data)(luat_lcd_conf_t* conf,const uint8_t cmd, const uint8_t *data, uint8_t data_len, uint8_t dummy_bit);
@@ -111,6 +127,7 @@ extern luat_lcd_opts_t lcd_opts_st7735v;
 extern luat_lcd_opts_t lcd_opts_st7789;
 extern luat_lcd_opts_t lcd_opts_st7796;
 extern luat_lcd_opts_t lcd_opts_nv3037;
+extern luat_lcd_opts_t lcd_opts_jd9261t_inited;
 
 static inline luat_color_t color_swap(luat_color_t color) {
     luat_color_t tmp = (color >> 8) + ((color & 0xFF) << 8);
@@ -198,5 +215,8 @@ int luat_lcd_show_camera_in_service(void *camera_info, camera_cut_info_t *cut_in
  * @return 0无异常,其他失败
  */
 int luat_lcd_stop_show_camera(void);
+
+int luat_lcd_qspi_config(luat_lcd_conf_t* conf, luat_lcd_qspi_conf_t *qspi_config);
+int luat_lcd_qspi_auto_flush_on_off(luat_lcd_conf_t* conf, uint8_t on_off);
 #endif
 

+ 49 - 0
components/lcd/luat_lcd_jd9261t.c

@@ -0,0 +1,49 @@
+#include "luat_base.h"
+#include "luat_lcd.h"
+#include "luat_gpio.h"
+#include "luat_mem.h"
+#define LUAT_LOG_TAG "jd9261t"
+#include "luat_log.h"
+
+static int jd9261t_inited_init(luat_lcd_conf_t* conf)
+{
+	luat_lcd_qspi_conf_t auto_flush =
+	{
+			.write_4line_cmd = 0xde,
+			.vsync_reg = 0x61,
+			.hsync_cmd = 0xde,
+			.hsync_reg = 0x60,
+			.write_1line_cmd = 0xde,
+	};
+	uint8_t temp = 0x0b;
+    luat_gpio_set(conf->pin_rst, Luat_GPIO_LOW);
+    luat_rtos_task_sleep(10);
+    luat_gpio_set(conf->pin_rst, Luat_GPIO_HIGH);
+    luat_rtos_task_sleep(150);
+    luat_lcd_qspi_config(conf, &auto_flush);	//必须在第一个命令发送前就准备好
+    lcd_write_cmd_data(conf,0x36, &temp, 1);
+    luat_rtos_task_sleep(5);
+    if (!conf->buff)
+    {
+    	conf->buff = luat_heap_opt_zalloc(LUAT_HEAP_AUTO, conf->w * conf->h * ((conf->bpp <= 16)?2:4));
+    	conf->flush_y_min = conf->h;
+    	conf->flush_y_max = 0;
+    }
+    luat_lcd_qspi_auto_flush_on_off(conf, 1);
+    luat_gpio_set(conf->pin_pwr, Luat_GPIO_HIGH);
+    return 0;
+}
+
+luat_lcd_opts_t lcd_opts_jd9261t_inited = {
+    .name = "jd9261t_inited",
+    .init_cmds_len = 0,
+    .init_cmds = NULL,
+    .direction0 = 0x03,
+    .direction90 = 0x03,
+    .direction180 = 0x03,
+    .direction270 = 0x03,
+	.rb_swap = 1,
+	.no_ram_mode = 1,
+	.user_ctrl_init = jd9261t_inited_init,
+};
+

+ 23 - 0
components/lcd/luat_lib_lcd.c

@@ -54,6 +54,7 @@ static const lcd_reg_t lcd_regs[] = {
   {"ili9486", &lcd_opts_ili9486},
   {"nv3037",  &lcd_opts_nv3037},
   {"h050iwv", &lcd_opts_h050iwv},
+  {"jd9261t_inited", &lcd_opts_jd9261t_inited},
   {"", NULL} // 最后一个必须是空字符串
 };
 
@@ -121,6 +122,7 @@ static int l_lcd_init(lua_State* L) {
     }
 #endif
     memset(conf, 0, sizeof(luat_lcd_conf_t)); // 填充0,保证无脏数据
+    conf->bpp = 16;
     conf->lcd_cs_pin = LUAT_GPIO_NONE;
     conf->pin_dc = LUAT_GPIO_NONE;
     conf->pin_pwr = LUAT_GPIO_NONE;
@@ -260,6 +262,26 @@ static int l_lcd_init(lua_State* L) {
             if (LUA_TNUMBER == lua_gettable(L, 2)) {
                 conf->interface_mode = luaL_checkinteger(L, -1);
             }
+            lua_pushstring(L, "bus_speed");
+            if (LUA_TNUMBER == lua_gettable(L, 2)) {
+                conf->bus_speed = luaL_checkinteger(L, -1);
+            }
+            lua_pushstring(L, "flush_rate");
+            if (LUA_TNUMBER == lua_gettable(L, 2)) {
+                conf->flush_rate = luaL_checkinteger(L, -1);
+            }
+            lua_pushstring(L, "vfp");
+            if (LUA_TNUMBER == lua_gettable(L, 2)) {
+                conf->vfp = luaL_checkinteger(L, -1);
+            }
+            lua_pushstring(L, "vbp");
+            if (LUA_TNUMBER == lua_gettable(L, 2)) {
+                conf->vbp = luaL_checkinteger(L, -1);
+            }
+            lua_pushstring(L, "vs");
+            if (LUA_TNUMBER == lua_gettable(L, 2)) {
+                conf->vs = luaL_checkinteger(L, -1);
+            }
             lua_pop(L, 1);
 
         }
@@ -1920,6 +1942,7 @@ static const rotable_Reg_t reg_lcd[] =
     { "WIRE_4_BIT_8_INTERFACE_II",  ROREG_INT(LUAT_LCD_IM_4_WIRE_8_BIT_INTERFACE_II)},
     //@const DATA_2_LANE int 双通道模式
     { "DATA_2_LANE",                ROREG_INT(LUAT_LCD_IM_2_DATA_LANE)},
+	{ "QSPI_MODE",                ROREG_INT(LUAT_LCD_IM_QSPI_MODE)},
 	  {NULL, ROREG_INT(0)}
 };
 

+ 8 - 3
demo/lcd/main.lua

@@ -44,7 +44,7 @@ if wdt then
 end
 
 local rtos_bsp = rtos.bsp()
-
+local chip_type = hmeta.chip()
 -- 根据不同的BSP返回不同的值
 -- spi_id,pin_reset,pin_dc,pin_cs,bl
 function lcd_pin()
@@ -60,7 +60,7 @@ function lcd_pin()
         return 2,16,15,14,13
     elseif rtos_bsp == "EC618" then
         return 0,1,10,8,22
-    elseif string.find(rtos_bsp,"EC718") then
+    elseif string.find(rtos_bsp,"EC718") or string.find(chip_type,"EC718") then
         return lcd.HWID_0,36,0xff,0xff,25 -- 注意:EC718P有硬件lcd驱动接口, 无需使用spi,当然spi驱动也支持
     else
         log.info("main", "bsp not support")
@@ -92,7 +92,11 @@ end
     --lcd.invoff()
     --0.96寸TFT如果显示依旧不正常,可以尝试老版本的板子的驱动
     -- lcd.init("st7735s",{port = port,pin_dc = pin_dc, pin_pwr = bl, pin_rst = pin_reset,direction = 2,w = 160,h = 80,xoffset = 0,yoffset = 0},spi_lcd)
-
+	
+	--lcd.init("jd9261t_inited",{port = port,pin_dc = pin_dc, pin_pwr = bl, pin_rst = pin_reset,direction = 0,w = 480,h = 480,xoffset = 0,yoffset = 0,interface_mode=lcd.QSPI_MODE,bus_speed=60000000,flush_rate=658,vbp=19,vfp=108,vs=2},spi_lcd)
+    --lcd.setupBuff(nil, true) -- 使用sys内存, 只需要选一种
+    --lcd.autoFlush(false)
+	
 -- 不在内置驱动的, 看demo/lcd_custom
 
 sys.taskInit(function()
@@ -114,6 +118,7 @@ sys.taskInit(function()
         log.info("lcd.drawLine", lcd.drawLine(20,20,150,20,0x001F))
         log.info("lcd.drawRectangle", lcd.drawRectangle(20,40,120,70,0xF800))
         log.info("lcd.drawCircle", lcd.drawCircle(50,50,20,0x0CE0))
+		lcd.flush()
         sys.wait(1000)
     end
 end)