瀏覽代碼

[add] proting 'lvgl' for stm32f407-atk-explorer.

liuxianliang 3 年之前
父節點
當前提交
8e50ef53d5
共有 21 個文件被更改,包括 3021 次插入75 次删除
  1. 5 3
      bsp/stm32/stm32f407-atk-explorer/README.md
  2. 16 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/SConscript
  3. 16 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/demo/SConscript
  4. 51 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/demo/lv_demo_calendar.c
  5. 6 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/demo/lv_demo_calendar.h
  6. 26 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_conf.h
  7. 65 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_demo.c
  8. 70 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_port_disp.c
  9. 23 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_port_disp.h
  10. 46 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_port_indev.c
  11. 28 0
      bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_port_indev.h
  12. 4 2
      bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c
  13. 48 11
      bsp/stm32/stm32f407-atk-explorer/board/Kconfig
  14. 9 3
      bsp/stm32/stm32f407-atk-explorer/board/SConscript
  15. 14 4
      bsp/stm32/stm32f407-atk-explorer/board/linker_scripts/link.lds
  16. 1988 0
      bsp/stm32/stm32f407-atk-explorer/board/ports/drv_lcd.c
  17. 74 0
      bsp/stm32/stm32f407-atk-explorer/board/ports/drv_lcd.h
  18. 208 0
      bsp/stm32/stm32f407-atk-explorer/board/ports/touch/drv_touch.c
  19. 55 0
      bsp/stm32/stm32f407-atk-explorer/board/ports/touch/drv_touch.h
  20. 240 0
      bsp/stm32/stm32f407-atk-explorer/board/ports/touch/drv_touch_ft.c
  21. 29 52
      bsp/stm32/stm32f407-atk-explorer/rtconfig.h

+ 5 - 3
bsp/stm32/stm32f407-atk-explorer/README.md

@@ -44,7 +44,9 @@
 | COM3         |  支持   |                                           |
 | MPU6050      |     支持     |                                       |
 | Flash        |   支持   |                               |
-| SRAM         |   支持   |                               |
+| SRAM         |   支持   |  LVGL 会使用到,但此时不能启用 RT_USING_MEMHEAP_AS_HEAP 内存算法 |
+| TFTLCD       |   支持   | F407 不带 LTDC 外设,所以需要使用 MCU LCD,而不能直接驱动 RGB 屏幕 |
+| LCD-TOUCH    |   支持   | 仅测试过 GT9147, 其他触摸驱动需要添加适配 |
 | SD卡         |   支持   | 支持FATFS文件系统 |
 | W25Q128 | 支持 | 支持LittleFS文件系统 |
 | 以太网       |   支持   |                               |
@@ -53,7 +55,7 @@
 | GPIO         |     支持     | PA0, PA1... PH1 ---> PIN: 0, 1...144 |
 | UART         |     支持     |              UART1/2/3              |
 | SPI          |     支持     |               SPI1/2/3                |
-| I2C          |     支持     |               软件 I2C                |
+| I2C          |     支持     |      软件 I2C1, I2C2[仅触摸屏使用]     |
 | ADC          |     支持     |                                       |
 | RTC          |     支持     | 支持外部晶振和内部低速时钟 |
 | WDT          |     支持     |                                       |
@@ -129,4 +131,4 @@ msh >
 
 维护人:
 
-- [guozhanxin](https://github.com/Guozhanxin) 
+- [guozhanxin](https://github.com/Guozhanxin)

+ 16 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/SConscript

@@ -0,0 +1,16 @@
+from building import *
+import os
+
+cwd = GetCurrentDir()
+group = []
+src = Glob('*.c')
+CPPPATH = [cwd]
+
+list = os.listdir(cwd)
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        group = group + SConscript(os.path.join(d, 'SConscript'))
+
+group += DefineGroup('LVGL-port', src, depend = ['PKG_USING_LVGL'], CPPPATH = CPPPATH)
+Return('group')

+ 16 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/demo/SConscript

@@ -0,0 +1,16 @@
+from building import *
+import os
+
+cwd = GetCurrentDir()
+group = []
+src = Glob('*.c')
+CPPPATH = [cwd]
+
+list = os.listdir(cwd)
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        group = group + SConscript(os.path.join(d, 'SConscript'))
+
+group += DefineGroup('LVGL-port', src, depend = ['PKG_USING_LVGL'], CPPPATH = CPPPATH)
+Return('group')

+ 51 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/demo/lv_demo_calendar.c

@@ -0,0 +1,51 @@
+#include <lvgl.h>
+#include "lv_demo_calendar.h"
+#include <board.h>
+#include <drv_lcd.h>
+
+static void event_handler(lv_event_t * e)
+{
+    lv_event_code_t code = lv_event_get_code(e);
+    lv_obj_t * obj = lv_event_get_current_target(e);
+
+    if(code == LV_EVENT_VALUE_CHANGED) {
+        lv_calendar_date_t date;
+        if(lv_calendar_get_pressed_date(obj, &date)) {
+            LV_LOG_USER("Clicked date: %02d.%02d.%d", date.day, date.month, date.year);
+        }
+    }
+}
+
+void lv_demo_calendar(void)
+{
+    lv_obj_t  * calendar = lv_calendar_create(lv_scr_act());
+    lv_obj_set_size(calendar, LCD_W, LCD_H);
+    lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 0);
+    lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL);
+
+    lv_calendar_set_today_date(calendar, 2021, 02, 23);
+    lv_calendar_set_showed_date(calendar, 2021, 02);
+
+    /*Highlight a few days*/
+    static lv_calendar_date_t highlighted_days[3];       /*Only its pointer will be saved so should be static*/
+    highlighted_days[0].year = 2021;
+    highlighted_days[0].month = 02;
+    highlighted_days[0].day = 6;
+
+    highlighted_days[1].year = 2021;
+    highlighted_days[1].month = 02;
+    highlighted_days[1].day = 11;
+
+    highlighted_days[2].year = 2022;
+    highlighted_days[2].month = 02;
+    highlighted_days[2].day = 22;
+
+    lv_calendar_set_highlighted_dates(calendar, highlighted_days, 3);
+
+#if LV_USE_CALENDAR_HEADER_DROPDOWN
+    lv_calendar_header_dropdown_create(calendar);
+#elif LV_USE_CALENDAR_HEADER_ARROW
+    lv_calendar_header_arrow_create(calendar);
+#endif
+    lv_calendar_set_showed_date(calendar, 2021, 10);
+}

+ 6 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/demo/lv_demo_calendar.h

@@ -0,0 +1,6 @@
+#ifndef __LV_DEMO_CALENDAR_H__
+#define __LV_DEMO_CALENDAR_H__
+
+void lv_demo_calendar(void);
+
+#endif

+ 26 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_conf.h

@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author        Notes
+ * 2021-10-18     Meco Man      First version
+ */
+
+#ifndef LV_CONF_H
+#define LV_CONF_H
+
+#define LV_COLOR_16_SWAP 0
+#define LV_COLOR_DEPTH 16
+#define LV_USE_PERF_MONITOR 1
+
+#include <rtconfig.h>
+#define LV_HOR_RES_MAX          800
+#define LV_VER_RES_MAX          480
+#define LV_USE_DEMO_RTT_MUSIC       1
+#define LV_DEMO_RTT_MUSIC_AUTO_PLAY 1
+#define LV_FONT_MONTSERRAT_12       1
+#define LV_FONT_MONTSERRAT_16       1
+
+#endif

+ 65 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_demo.c

@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author        Notes
+ * 2021-10-17     Meco Man      First version
+ */
+#include <rtthread.h>
+#include <lvgl.h>
+#include <lv_port_indev.h>
+#include <lv_demo_calendar.h>
+#define DBG_TAG    "LVGL.demo"
+#define DBG_LVL    DBG_INFO
+#include <rtdbg.h>
+
+#ifndef LV_THREAD_STACK_SIZE
+#define LV_THREAD_STACK_SIZE 4096
+#endif
+
+#ifndef LV_THREAD_PRIO
+#define LV_THREAD_PRIO (RT_THREAD_PRIORITY_MAX*2/3)
+#endif
+
+static void lvgl_thread(void *parameter)
+{
+    /*assign buttons to coordinates*/
+    const lv_point_t points_array[] =  {{200,35},{0,0},{70,35},{0,0}};
+    lv_indev_set_button_points(button_indev, points_array);
+
+    /* display demo; you may replace with your LVGL application at here */
+#ifdef PKG_USING_LV_MUSIC_DEMO
+    extern void lv_demo_music(void);
+    lv_demo_music();
+#else
+    lv_demo_calendar();
+#endif
+
+    /* handle the tasks of LVGL */
+    while(1)
+    {
+        lv_task_handler();
+        rt_thread_mdelay(10);
+    }
+}
+
+static int lvgl_demo_init(void)
+{
+    rt_thread_t tid;
+    rt_device_t lcd = RT_NULL;
+
+    lcd = rt_device_find("lcd");
+    rt_device_init(lcd);
+
+    tid = rt_thread_create("LVGL", lvgl_thread, RT_NULL, LV_THREAD_STACK_SIZE, LV_THREAD_PRIO, 0);
+    if(tid == RT_NULL)
+    {
+        LOG_E("Fail to create 'LVGL' thread");
+    }
+    rt_thread_startup(tid);
+
+    return 0;
+}
+INIT_APP_EXPORT(lvgl_demo_init);

+ 70 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_port_disp.c

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-10-18     Meco Man     The first version
+ */
+#include <lvgl.h>
+#include <board.h>
+#include <drv_lcd.h>
+
+// #define MY_DISP_HOR_RES LCD_W
+// #define DISP_BUFFER_LINES 70
+
+/*A static or global variable to store the buffers*/
+static lv_disp_draw_buf_t disp_buf;
+
+/*Descriptor of a display driver*/
+static lv_disp_drv_t disp_drv;
+
+/*Static or global buffer(s). The second buffer is optional*/
+#if defined ( __ICCARM__ ) /*!< IAR Compiler */
+#pragma location=0x68000000
+lv_color_t buf_1[LCD_H * LCD_W];
+#elif defined ( __CC_ARM )  /* MDK ARM Compiler */
+__attribute__((at(0x68000000))) lv_color_t buf_1[LCD_H * LCD_W];
+#elif defined ( __CLANG_ARM ) /* MDK ARM Compiler v6 */
+__attribute__((section(".ARM.__at_0x68000000"))) lv_color_t buf_1[LCD_H * LCD_W];
+#elif defined ( __GNUC__ ) /* GNU Compiler */
+lv_color_t buf_1[LCD_H * LCD_W] __attribute__((section(".MCUlcdgrambysram")));
+#ifdef RT_USING_MEMHEAP_AS_HEAP
+#error "You should modify this logic, such as use 'rt_malloc' to create lvgl buf"
+#endif
+#endif
+
+/*Flush the content of the internal buffer the specific area on the display
+ *You can use DMA or any hardware acceleration to do this operation in the background but
+ *'lv_disp_flush_ready()' has to be called when finished.*/
+static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
+{
+    /* color_p is a buffer pointer; the buffer is provided by LVGL */
+    lcd_fill_array(area->x1, area->y1, area->x2, area->y2, color_p);
+
+    /*IMPORTANT!!!
+     *Inform the graphics library that you are ready with the flushing*/
+    lv_disp_flush_ready(disp_drv);
+}
+
+void lv_port_disp_init(void)
+{
+    /*Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */
+    lv_disp_draw_buf_init(&disp_buf, buf_1, NULL, LCD_H * LCD_W);
+
+    lv_disp_drv_init(&disp_drv); /*Basic initialization*/
+
+    /*Set the resolution of the display*/
+    disp_drv.hor_res = LCD_W;
+    disp_drv.ver_res = LCD_H;
+
+    /*Set a display buffer*/
+    disp_drv.draw_buf = &disp_buf;
+
+    /*Used to copy the buffer's content to the display*/
+    disp_drv.flush_cb = disp_flush;
+
+    /*Finally register the driver*/
+    lv_disp_drv_register(&disp_drv);
+}

+ 23 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_port_disp.h

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-10-18     Meco Man     The first version
+ */
+#ifndef LV_PORT_DISP_H
+#define LV_PORT_DISP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void lv_port_disp_init(void);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif

+ 46 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_port_indev.c

@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-10-18     Meco Man     The first version
+ */
+#include <lvgl.h>
+#include <stdbool.h>
+#include <rtdevice.h>
+#include <board.h>
+#include <drv_lcd.h>
+
+static lv_indev_state_t last_state = LV_INDEV_STATE_REL;
+static rt_int16_t last_x = 0;
+static rt_int16_t last_y = 0;
+
+static void input_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
+{
+    data->point.x = last_x;
+    data->point.y = last_y;
+    data->state = last_state;
+}
+
+void lv_port_indev_input(rt_int16_t x, rt_int16_t y, lv_indev_state_t state)
+{
+    last_state = state;
+    last_x = LCD_W - y;
+    last_y = x;
+}
+
+lv_indev_t * button_indev;
+
+void lv_port_indev_init(void)
+{
+    static lv_indev_drv_t indev_drv;
+
+    lv_indev_drv_init(&indev_drv); /*Basic initialization*/
+    indev_drv.type = LV_INDEV_TYPE_POINTER;
+    indev_drv.read_cb = input_read;
+
+    /*Register the driver in LVGL and save the created input device object*/
+    button_indev = lv_indev_drv_register(&indev_drv);
+}

+ 28 - 0
bsp/stm32/stm32f407-atk-explorer/applications/lvgl/lv_port_indev.h

@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-10-18     Meco Man     The first version
+ */
+#ifndef LV_PORT_INDEV_H
+#define LV_PORT_INDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <lv_hal_indev.h>
+
+extern lv_indev_t * button_indev;
+
+void lv_port_indev_init(void);
+void lv_port_indev_input(rt_int16_t x, rt_int16_t y, lv_indev_state_t state);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif

+ 4 - 2
bsp/stm32/stm32f407-atk-explorer/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c

@@ -953,6 +953,7 @@ static void HAL_FSMC_MspInit(void){
   PD4   ------> FSMC_NOE
   PD5   ------> FSMC_NWE
   PG10   ------> FSMC_NE3
+  PG12   ------> FSMC_NE4
   PE0   ------> FSMC_NBL0
   PE1   ------> FSMC_NBL1
   */
@@ -966,7 +967,7 @@ static void HAL_FSMC_MspInit(void){
   HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 
   GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
-                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10;
+                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10|GPIO_PIN_12;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
@@ -1058,6 +1059,7 @@ static void HAL_FSMC_MspDeInit(void){
   PD4   ------> FSMC_NOE
   PD5   ------> FSMC_NWE
   PG10   ------> FSMC_NE3
+  PG12   ------> FSMC_NE4
   PE0   ------> FSMC_NBL0
   PE1   ------> FSMC_NBL1
   */
@@ -1066,7 +1068,7 @@ static void HAL_FSMC_MspDeInit(void){
                           |GPIO_PIN_14|GPIO_PIN_15);
 
   HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
-                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10);
+                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10|GPIO_PIN_12);
 
   HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
                           |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14

+ 48 - 11
bsp/stm32/stm32f407-atk-explorer/board/Kconfig

@@ -27,13 +27,33 @@ menu "Onboard Peripheral Drivers"
         select BSP_USING_UART
         select BSP_USING_UART3
         default n
-    
+
     config BSP_USING_SRAM
         bool "Enable SRAM"
         select BSP_USING_EXT_FMC_IO
         select BSP_USING_FMC
         default n
 
+    config BSP_USING_MCU_LCD
+        bool "Enable ATK LCD"
+        select BSP_USING_SDRAM
+        default n
+        if BSP_USING_MCU_LCD
+            config BSP_USING_MCU_LCD_TEST
+                bool "Enable lcd fill test"
+                default y
+        endif
+
+    config BSP_USING_TOUCH
+        bool "Use LCD TOUCH"
+        select BSP_USING_I2C2
+        default n
+        if BSP_USING_TOUCH
+            config BSP_TOUCH_INT_PIN
+                int "Touch interrupt pin, PB1"
+                default 17
+        endif
+
     config BSP_USING_SPI_FLASH
         bool "Enable SPI FLASH (W25Q128 spi1)"
         select BSP_USING_SPI
@@ -46,7 +66,7 @@ menu "Onboard Peripheral Drivers"
         bool "Enable I2C EEPROM (i2c1)"
         select BSP_USING_I2C1
         default n
-    
+
     config BSP_USING_ETH
         bool "Enable Ethernet"
         default n
@@ -96,7 +116,7 @@ menu "Onboard Peripheral Drivers"
             select RT_USING_DFS
             select RT_USING_DFS_ROMFS
             select RT_USING_MTD_NOR
-            select BSP_USING_SPI_FLASH            
+            select BSP_USING_SPI_FLASH
             select BSP_USING_FS
             select PKG_USING_FAL
             select FAL_USING_AUTO_INIT
@@ -155,7 +175,7 @@ menu "On-chip Peripheral Drivers"
             config BSP_UART3_RX_USING_DMA
                 bool "Enable UART3 RX DMA"
                 depends on BSP_USING_UART3 && RT_SERIAL_USING_DMA
-                default n  
+                default n
 
             config BSP_UART3_TX_USING_DMA
                 bool "Enable UART3 TX DMA"
@@ -169,7 +189,7 @@ menu "On-chip Peripheral Drivers"
             config BSP_UART4_RX_USING_DMA
                 bool "Enable UART4 RX DMA"
                 depends on BSP_USING_UART4 && RT_SERIAL_USING_DMA
-                default n  
+                default n
 
             config BSP_UART4_TX_USING_DMA
                 bool "Enable UART4 TX DMA"
@@ -183,7 +203,7 @@ menu "On-chip Peripheral Drivers"
             config BSP_UART5_RX_USING_DMA
                 bool "Enable UART5 RX DMA"
                 depends on BSP_USING_UART5 && RT_SERIAL_USING_DMA
-                default n  
+                default n
 
             config BSP_UART5_TX_USING_DMA
                 bool "Enable UART5 TX DMA"
@@ -197,7 +217,7 @@ menu "On-chip Peripheral Drivers"
             config BSP_UART6_RX_USING_DMA
                 bool "Enable UART6 RX DMA"
                 depends on BSP_USING_UART6 && RT_SERIAL_USING_DMA
-                default n  
+                default n
 
             config BSP_UART6_TX_USING_DMA
                 bool "Enable UART6 TX DMA"
@@ -255,7 +275,7 @@ menu "On-chip Peripheral Drivers"
                 bool "Enable SPI1 TX DMA"
                 depends on BSP_USING_SPI1
                 default n
-                
+
             config BSP_SPI1_RX_USING_DMA
                 bool "Enable SPI1 RX DMA"
                 depends on BSP_USING_SPI1
@@ -270,7 +290,7 @@ menu "On-chip Peripheral Drivers"
                 bool "Enable SPI2 TX DMA"
                 depends on BSP_USING_SPI2
                 default n
-                
+
             config BSP_SPI2_RX_USING_DMA
                 bool "Enable SPI2 RX DMA"
                 depends on BSP_USING_SPI2
@@ -305,6 +325,23 @@ menu "On-chip Peripheral Drivers"
                 default 25
         endif
 
+    menuconfig BSP_USING_I2C2
+        bool "Enable LCD Touch BUS (software simulation)"
+        default y
+        select RT_USING_I2C
+        select RT_USING_I2C_BITOPS
+        select RT_USING_PIN
+        if BSP_USING_I2C2
+            config BSP_I2C2_SCL_PIN
+                int "i2c2 scl pin number, PB0"
+                range 0 143
+                default 16
+            config BSP_I2C2_SDA_PIN
+                int "I2C2 sda pin number, PF11"
+                range 0 143
+                default 91
+        endif
+
     menuconfig BSP_USING_DAC
         bool "Enable DAC"
         default n
@@ -373,7 +410,7 @@ menu "On-chip Peripheral Drivers"
                 default n
 
         endif
-    
+
     config BSP_USING_EXT_FMC_IO
         bool
         default n
@@ -382,7 +419,7 @@ menu "On-chip Peripheral Drivers"
         bool
         default n
  source "../libraries/HAL_Drivers/Kconfig"
-    
+
 endmenu
 
 menu "Board extended module Drivers"

+ 9 - 3
bsp/stm32/stm32f407-atk-explorer/board/SConscript

@@ -11,6 +11,9 @@ src = Split('''
 board.c
 CubeMX_Config/Src/stm32f4xx_hal_msp.c
 ''')
+path =  [cwd]
+path += [cwd + '/CubeMX_Config/Inc']
+path += [cwd + '/ports']
 
 if GetDepend(['BSP_USING_ETH']):
     src += Glob('ports/phy_reset.c')
@@ -26,9 +29,12 @@ if GetDepend(['BSP_USING_FS']):
 if GetDepend(['BSP_USING_SRAM']):
     src += Glob('ports/drv_sram.c')
 
-path =  [cwd]
-path += [cwd + '/CubeMX_Config/Inc']
-path += [cwd + '/ports']
+if GetDepend(['BSP_USING_MCU_LCD']):
+    src += Glob('ports/drv_lcd.c')
+
+if GetDepend(['BSP_USING_TOUCH']):
+    src += Glob('ports/touch/*.c')
+    path += [cwd + '/ports/touch']
 
 startup_path_prefix = SDK_LIB
 

+ 14 - 4
bsp/stm32/stm32f407-atk-explorer/board/linker_scripts/link.lds

@@ -10,6 +10,7 @@ MEMORY
     CODE (rx) : ORIGIN = 0x08000000, LENGTH = 1024k /* 1024KB flash */
     RAM1 (rw) : ORIGIN = 0x20000000, LENGTH =  128k /* 128K sram */
     RAM2 (rw) : ORIGIN = 0x10000000, LENGTH =   64k /* 64K sram */
+    MCUlcdgrambysram (rw) : ORIGIN =0x68000000, LENGTH = 1024k
 }
 ENTRY(Reset_Handler)
 _system_stack_size = 0x400;
@@ -54,9 +55,9 @@ SECTIONS
         KEEP (*(SORT(.init_array.*)))
         KEEP (*(.init_array))
         PROVIDE(__ctors_end__ = .);
-        
+
         . = ALIGN(4);
-        
+
         _etext = .;
     } > CODE = 0
 
@@ -93,7 +94,7 @@ SECTIONS
         _edata = . ;
     } >RAM1
 
-    .stack : 
+    .stack :
     {
         . = ALIGN(4);
         _sstack = .;
@@ -116,11 +117,20 @@ SECTIONS
         . = ALIGN(4);
         /* This is used by the startup in order to initialize the .bss secion */
         _ebss = . ;
-        
+
         *(.bss.init)
     } > RAM1
     __bss_end = .;
 
+    .MCUlcdgrambysram (NOLOAD) : ALIGN(4)
+    {
+        . = ALIGN(4);
+        *(.MCUlcdgrambysram)
+        *(.MCUlcdgrambysram.*)
+        . = ALIGN(4);
+        __MCUlcdgrambysram_free__ = .;
+    } > MCUlcdgrambysram
+
     _end = .;
 
     /* Stabs debugging sections.  */

+ 1988 - 0
bsp/stm32/stm32f407-atk-explorer/board/ports/drv_lcd.c

@@ -0,0 +1,1988 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-12-28     unknow       copy by STemwin
+ * 2021-12-29     xiangxistu   port for lvgl <lcd_fill_array>
+ */
+
+#include <board.h>
+#include "drv_lcd.h"
+#include "string.h"
+
+//#define DRV_DEBUG
+#define LOG_TAG "drv.lcd"
+#include <drv_log.h>
+
+_lcd_dev lcddev;
+SRAM_HandleTypeDef hsram1;
+
+#define LCD_BL GET_PIN(B, 15)
+#define LCD_BASE ((uint32_t)(0x6C000000 | 0x0000007E))
+#define LCD ((LCD_CONTROLLER_TypeDef *)LCD_BASE)
+
+#define LCD_DEVICE(dev) (struct drv_lcd_device *)(dev)
+
+struct drv_lcd_device
+{
+    struct rt_device parent;
+
+    struct rt_device_graphic_info lcd_info;
+};
+
+static struct drv_lcd_device _lcd;
+
+//写寄存器函数
+//regval:寄存器值
+void LCD_WR_REG(uint16_t regval)
+{
+    LCD->REG = regval; //写入要写的寄存器序号
+}
+//写LCD数据
+//data:要写入的值
+void LCD_WR_DATA(uint16_t data)
+{
+    LCD->RAM = data;
+}
+//读LCD数据
+//返回值:读到的值
+uint16_t LCD_RD_DATA(void)
+{
+    return LCD->RAM;
+}
+//写寄存器
+//LCD_Reg:寄存器地址
+//LCD_RegValue:要写入的数据
+void LCD_WriteReg(uint16_t LCD_Reg, uint16_t LCD_RegValue)
+{
+    LCD->REG = LCD_Reg;      //写入要写的寄存器序号
+    LCD->RAM = LCD_RegValue; //写入数据
+}
+//读寄存器
+//LCD_Reg:寄存器地址
+//返回值:读到的数据
+uint16_t LCD_ReadReg(uint16_t LCD_Reg)
+{
+    LCD_WR_REG(LCD_Reg);  //写入要读的寄存器序号
+    return LCD_RD_DATA(); //返回读到的值
+}
+//开始写GRAM
+void LCD_WriteRAM_Prepare(void)
+{
+    LCD->REG = lcddev.wramcmd;
+}
+//LCD写GRAM
+//RGB_Code:颜色值
+void LCD_WriteRAM(uint16_t RGB_Code)
+{
+    LCD->RAM = RGB_Code; //写十六位GRAM
+}
+
+//从ILI93xx读出的数据为GBR格式,而我们写入的时候为RGB格式。
+//通过该函数转换
+//c:GBR格式的颜色值
+//返回值:RGB格式的颜色值
+uint16_t LCD_BGR2RGB(uint16_t c)
+{
+    uint16_t r, g, b, rgb;
+    b = (c >> 0) & 0x1f;
+    g = (c >> 5) & 0x3f;
+    r = (c >> 11) & 0x1f;
+    rgb = (b << 11) + (g << 5) + (r << 0);
+    return (rgb);
+}
+
+//设置光标位置(对RGB屏无效)
+//Xpos:横坐标
+//Ypos:纵坐标
+void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos)
+{
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310)
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(Xpos >> 8);
+        LCD_WR_DATA(Xpos & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(Ypos >> 8);
+        LCD_WR_DATA(Ypos & 0XFF);
+    }
+    else if (lcddev.id == 0X1963)
+    {
+        if (lcddev.dir == 0) //x坐标需要变换
+        {
+            Xpos = lcddev.width - 1 - Xpos;
+            LCD_WR_REG(lcddev.setxcmd);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA(Xpos >> 8);
+            LCD_WR_DATA(Xpos & 0XFF);
+        }
+        else
+        {
+            LCD_WR_REG(lcddev.setxcmd);
+            LCD_WR_DATA(Xpos >> 8);
+            LCD_WR_DATA(Xpos & 0XFF);
+            LCD_WR_DATA((lcddev.width - 1) >> 8);
+            LCD_WR_DATA((lcddev.width - 1) & 0XFF);
+        }
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(Ypos >> 8);
+        LCD_WR_DATA(Ypos & 0XFF);
+        LCD_WR_DATA((lcddev.height - 1) >> 8);
+        LCD_WR_DATA((lcddev.height - 1) & 0XFF);
+    }
+    else if (lcddev.id == 0X5510)
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(Xpos >> 8);
+        LCD_WR_REG(lcddev.setxcmd + 1);
+        LCD_WR_DATA(Xpos & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(Ypos >> 8);
+        LCD_WR_REG(lcddev.setycmd + 1);
+        LCD_WR_DATA(Ypos & 0XFF);
+    }
+}
+
+//读取个某点的颜色值
+//x,y:坐标
+//返回值:此点的颜色
+void LCD_ReadPoint(char *pixel, int x, int y)
+{
+    uint16_t *color = (uint16_t *)pixel;
+    uint16_t r = 0, g = 0, b = 0;
+    if (x >= lcddev.width || y >= lcddev.height)
+    {
+        *color = 0; //超过了范围,直接返回
+        return;
+    }
+    LCD_SetCursor(x, y);
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310 || lcddev.id == 0X1963)
+        LCD_WR_REG(0X2E); //9341/3510/1963 发送读GRAM指令
+    else if (lcddev.id == 0X5510)
+        LCD_WR_REG(0X2E00); //5510 发送读GRAM指令
+    r = LCD_RD_DATA();      //dummy Read
+    if (lcddev.id == 0X1963)
+    {
+        *color = r;
+        return; //1963直接读就可以
+    }
+
+    r = LCD_RD_DATA(); //实际坐标颜色
+    //9341/NT35310/NT35510要分2次读出
+
+    b = LCD_RD_DATA();
+    g = r & 0XFF; //对于9341/5310/5510,第一次读取的是RG的值,R在前,G在后,各占8位
+    g <<= 8;
+    *color = (((r >> 11) << 11) | ((g >> 10) << 5) | (b >> 11)); //ILI9341/NT35310/NT35510需要公式转换一下
+}
+//LCD开启显示
+void LCD_DisplayOn(void)
+{
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310 || lcddev.id == 0X1963)
+        LCD_WR_REG(0X29); //开启显示
+    else if (lcddev.id == 0X5510)
+        LCD_WR_REG(0X2900); //开启显示
+}
+//LCD关闭显示
+void LCD_DisplayOff(void)
+{
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310 || lcddev.id == 0X1963)
+        LCD_WR_REG(0X28); //关闭显示
+    else if (lcddev.id == 0X5510)
+        LCD_WR_REG(0X2800); //关闭显示
+}
+
+//设置LCD的自动扫描方向(对RGB屏无效)
+//注意:其他函数可能会受到此函数设置的影响(尤其是9341),
+//所以,一般设置为L2R_U2D即可,如果设置为其他扫描方式,可能导致显示不正常.
+//dir:0~7,代表8个方向(具体定义见lcd.h)
+//9341/5310/5510/1963等IC已经实际测试
+void LCD_Scan_Dir(uint8_t dir)
+{
+    uint16_t regval = 0;
+    uint16_t dirreg = 0;
+    uint16_t temp;
+    if ((lcddev.dir == 1 && lcddev.id != 0X1963) || (lcddev.dir == 0 && lcddev.id == 0X1963)) //横屏时,对1963不改变扫描方向!竖屏时1963改变方向
+    {
+        switch (dir) //方向转换
+        {
+        case 0:
+            dir = 6;
+            break;
+        case 1:
+            dir = 7;
+            break;
+        case 2:
+            dir = 4;
+            break;
+        case 3:
+            dir = 5;
+            break;
+        case 4:
+            dir = 1;
+            break;
+        case 5:
+            dir = 0;
+            break;
+        case 6:
+            dir = 3;
+            break;
+        case 7:
+            dir = 2;
+            break;
+        }
+    }
+    if (lcddev.id == 0x9341 || lcddev.id == 0X5310 || lcddev.id == 0X5510 || lcddev.id == 0X1963) //9341/5310/5510/1963,特殊处理
+    {
+        switch (dir)
+        {
+        case L2R_U2D: //从左到右,从上到下
+            regval |= (0 << 7) | (0 << 6) | (0 << 5);
+            break;
+        case L2R_D2U: //从左到右,从下到上
+            regval |= (1 << 7) | (0 << 6) | (0 << 5);
+            break;
+        case R2L_U2D: //从右到左,从上到下
+            regval |= (0 << 7) | (1 << 6) | (0 << 5);
+            break;
+        case R2L_D2U: //从右到左,从下到上
+            regval |= (1 << 7) | (1 << 6) | (0 << 5);
+            break;
+        case U2D_L2R: //从上到下,从左到右
+            regval |= (0 << 7) | (0 << 6) | (1 << 5);
+            break;
+        case U2D_R2L: //从上到下,从右到左
+            regval |= (0 << 7) | (1 << 6) | (1 << 5);
+            break;
+        case D2U_L2R: //从下到上,从左到右
+            regval |= (1 << 7) | (0 << 6) | (1 << 5);
+            break;
+        case D2U_R2L: //从下到上,从右到左
+            regval |= (1 << 7) | (1 << 6) | (1 << 5);
+            break;
+        }
+        if (lcddev.id == 0X5510)
+            dirreg = 0X3600;
+        else
+            dirreg = 0X36;
+        if ((lcddev.id != 0X5310) && (lcddev.id != 0X5510) && (lcddev.id != 0X1963))
+            regval |= 0X08; //5310/5510/1963不需要BGR
+        LCD_WriteReg(dirreg, regval);
+        if (lcddev.id != 0X1963) //1963不做坐标处理
+        {
+            if (regval & 0X20)
+            {
+                if (lcddev.width < lcddev.height) //交换X,Y
+                {
+                    temp = lcddev.width;
+                    lcddev.width = lcddev.height;
+                    lcddev.height = temp;
+                }
+            }
+            else
+            {
+                if (lcddev.width > lcddev.height) //交换X,Y
+                {
+                    temp = lcddev.width;
+                    lcddev.width = lcddev.height;
+                    lcddev.height = temp;
+                }
+            }
+        }
+        if (lcddev.id == 0X5510)
+        {
+            LCD_WR_REG(lcddev.setxcmd);
+            LCD_WR_DATA(0);
+            LCD_WR_REG(lcddev.setxcmd + 1);
+            LCD_WR_DATA(0);
+            LCD_WR_REG(lcddev.setxcmd + 2);
+            LCD_WR_DATA((lcddev.width - 1) >> 8);
+            LCD_WR_REG(lcddev.setxcmd + 3);
+            LCD_WR_DATA((lcddev.width - 1) & 0XFF);
+            LCD_WR_REG(lcddev.setycmd);
+            LCD_WR_DATA(0);
+            LCD_WR_REG(lcddev.setycmd + 1);
+            LCD_WR_DATA(0);
+            LCD_WR_REG(lcddev.setycmd + 2);
+            LCD_WR_DATA((lcddev.height - 1) >> 8);
+            LCD_WR_REG(lcddev.setycmd + 3);
+            LCD_WR_DATA((lcddev.height - 1) & 0XFF);
+        }
+        else
+        {
+            LCD_WR_REG(lcddev.setxcmd);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA((lcddev.width - 1) >> 8);
+            LCD_WR_DATA((lcddev.width - 1) & 0XFF);
+            LCD_WR_REG(lcddev.setycmd);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA(0);
+            LCD_WR_DATA((lcddev.height - 1) >> 8);
+            LCD_WR_DATA((lcddev.height - 1) & 0XFF);
+        }
+    }
+}
+
+//快速画点
+//x,y:坐标
+//color:颜色
+static void LCD_Fast_DrawPoint(const char *pixel, int x, int y)
+{
+    uint16_t color = *((uint16_t *)pixel);
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310)
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(x >> 8);
+        LCD_WR_DATA(x & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(y >> 8);
+        LCD_WR_DATA(y & 0XFF);
+    }
+    else if (lcddev.id == 0X5510)
+    {
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(x >> 8);
+        LCD_WR_REG(lcddev.setxcmd + 1);
+        LCD_WR_DATA(x & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(y >> 8);
+        LCD_WR_REG(lcddev.setycmd + 1);
+        LCD_WR_DATA(y & 0XFF);
+    }
+    else if (lcddev.id == 0X1963)
+    {
+        if (lcddev.dir == 0)
+            x = lcddev.width - 1 - x;
+        LCD_WR_REG(lcddev.setxcmd);
+        LCD_WR_DATA(x >> 8);
+        LCD_WR_DATA(x & 0XFF);
+        LCD_WR_DATA(x >> 8);
+        LCD_WR_DATA(x & 0XFF);
+        LCD_WR_REG(lcddev.setycmd);
+        LCD_WR_DATA(y >> 8);
+        LCD_WR_DATA(y & 0XFF);
+        LCD_WR_DATA(y >> 8);
+        LCD_WR_DATA(y & 0XFF);
+    }
+    LCD->REG = lcddev.wramcmd;
+    LCD->RAM = color;
+}
+//SSD1963 背光设置
+//pwm:背光等级,0~100.越大越亮.
+void LCD_SSD_BackLightSet(uint8_t pwm)
+{
+    LCD_WR_REG(0xBE);        //配置PWM输出
+    LCD_WR_DATA(0x05);       //1设置PWM频率
+    LCD_WR_DATA(pwm * 2.55); //2设置PWM占空比
+    LCD_WR_DATA(0x01);       //3设置C
+    LCD_WR_DATA(0xFF);       //4设置D
+    LCD_WR_DATA(0x00);       //5设置E
+    LCD_WR_DATA(0x00);       //6设置F
+}
+
+//设置LCD显示方向
+//dir:0,竖屏;1,横屏
+void LCD_Display_Dir(uint8_t dir)
+{
+    lcddev.dir = dir; //竖屏/横屏
+    if (dir == 0)     //竖屏
+    {
+        lcddev.width = 240;
+        lcddev.height = 320;
+        if (lcddev.id == 0X9341 || lcddev.id == 0X5310)
+        {
+            lcddev.wramcmd = 0X2C;
+            lcddev.setxcmd = 0X2A;
+            lcddev.setycmd = 0X2B;
+            if (lcddev.id == 0X5310)
+            {
+                lcddev.width = 320;
+                lcddev.height = 480;
+            }
+        }
+        else if (lcddev.id == 0x5510)
+        {
+            lcddev.wramcmd = 0X2C00;
+            lcddev.setxcmd = 0X2A00;
+            lcddev.setycmd = 0X2B00;
+            lcddev.width = 480;
+            lcddev.height = 800;
+        }
+        else if (lcddev.id == 0X1963)
+        {
+            lcddev.wramcmd = 0X2C; //设置写入GRAM的指令
+            lcddev.setxcmd = 0X2B; //设置写X坐标指令
+            lcddev.setycmd = 0X2A; //设置写Y坐标指令
+            lcddev.width = 480;    //设置宽度480
+            lcddev.height = 800;   //设置高度800
+        }
+    }
+    else //横屏
+    {
+        lcddev.width = 320;
+        lcddev.height = 240;
+        if (lcddev.id == 0X9341 || lcddev.id == 0X5310)
+        {
+            lcddev.wramcmd = 0X2C;
+            lcddev.setxcmd = 0X2A;
+            lcddev.setycmd = 0X2B;
+        }
+        else if (lcddev.id == 0x5510)
+        {
+            lcddev.wramcmd = 0X2C00;
+            lcddev.setxcmd = 0X2A00;
+            lcddev.setycmd = 0X2B00;
+            lcddev.width = 800;
+            lcddev.height = 480;
+        }
+        else if (lcddev.id == 0X1963)
+        {
+            lcddev.wramcmd = 0X2C; //设置写入GRAM的指令
+            lcddev.setxcmd = 0X2A; //设置写X坐标指令
+            lcddev.setycmd = 0X2B; //设置写Y坐标指令
+            lcddev.width = 800;    //设置宽度800
+            lcddev.height = 480;   //设置高度480
+        }
+        if (lcddev.id == 0X5310)
+        {
+            lcddev.width = 480;
+            lcddev.height = 320;
+        }
+    }
+    LCD_Scan_Dir(DFT_SCAN_DIR); //默认扫描方向
+}
+
+//清屏函数
+//color:要清屏的填充色
+void LCD_Clear(uint32_t color)
+{
+    uint32_t index = 0;
+    uint32_t totalpoint = lcddev.width;
+    totalpoint *= lcddev.height; //得到总点数
+    LCD_SetCursor(0x00, 0x0000); //设置光标位置
+    LCD_WriteRAM_Prepare();      //开始写入GRAM
+    for (index = 0; index < totalpoint; index++)
+    {
+        LCD->RAM = color;
+    }
+}
+
+void LCD_HLine(const char *pixel, int x1, int x2, int y)
+{
+    int xsize = x2 - x1 + 1;
+    LCD_SetCursor(x1, y);
+    LCD_WriteRAM_Prepare();
+    uint16_t *p = (uint16_t *)pixel;
+    for (; xsize > 0; xsize--)
+        LCD->RAM = *p;
+}
+
+void LCD_BlitLine(const char *pixel, int x, int y, rt_size_t size)
+{
+    LCD_SetCursor(x, y);
+    LCD_WriteRAM_Prepare();
+    uint16_t *p = (uint16_t *)pixel;
+    for (; size > 0; size--, p++)
+        LCD->RAM = *p;
+}
+
+void lcd_fill_array(rt_uint16_t x_start, rt_uint16_t y_start, rt_uint16_t x_end, rt_uint16_t y_end, void *pcolor)
+{
+    rt_uint16_t *pixel = RT_NULL;
+    rt_uint16_t cycle_y, x_offset = 0;
+
+    pixel = (rt_uint16_t *)pcolor;
+
+    for(cycle_y = y_start; cycle_y <= y_end; )
+    {
+        LCD_SetCursor(x_start, cycle_y);
+        LCD_WriteRAM_Prepare();
+        for(x_offset = 0;x_start + x_offset <= x_end; x_offset++)
+        {
+            LCD->RAM = *pixel++;
+        }
+        cycle_y++;
+    }
+}
+
+static rt_err_t drv_lcd_init(struct rt_device *device)
+{
+
+    __HAL_RCC_GPIOD_CLK_ENABLE();
+    __HAL_RCC_GPIOE_CLK_ENABLE();
+    __HAL_RCC_GPIOF_CLK_ENABLE();
+    __HAL_RCC_GPIOG_CLK_ENABLE();
+    __HAL_RCC_GPIOB_CLK_ENABLE();
+
+    FSMC_NORSRAM_TimingTypeDef Timing;
+
+    rt_pin_mode(LCD_BL, PIN_MODE_OUTPUT);
+
+    /** Perform the SRAM1 memory initialization sequence
+  */
+    hsram1.Instance = FSMC_NORSRAM_DEVICE;
+    hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
+    /* hsram1.Init */
+    hsram1.Init.NSBank = FSMC_NORSRAM_BANK4;
+    hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
+    hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
+    hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
+    hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
+    hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
+    hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
+    hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
+    hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
+    hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
+    hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
+    hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
+    hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
+    hsram1.Init.PageSize = FSMC_PAGE_SIZE_NONE;
+    /* Timing */
+    Timing.AddressSetupTime = 5;
+    Timing.AddressHoldTime = 1;
+    Timing.DataSetupTime = 9;
+    Timing.BusTurnAroundDuration = 0;
+    Timing.CLKDivision = 2;
+    Timing.DataLatency = 2;
+    Timing.AccessMode = FSMC_ACCESS_MODE_A;
+    /* ExtTiming */
+
+    if (HAL_SRAM_Init(&hsram1, &Timing, &Timing) != HAL_OK)
+    {
+        Error_Handler();
+    }
+
+    rt_thread_mdelay(50);
+
+    //尝试9341 ID的读取
+    LCD_WR_REG(0XD3);
+    lcddev.id = LCD_RD_DATA(); //dummy read
+    lcddev.id = LCD_RD_DATA(); //读到0X00
+    lcddev.id = LCD_RD_DATA(); //读取93
+    lcddev.id <<= 8;
+    lcddev.id |= LCD_RD_DATA(); //读取41
+    if (lcddev.id != 0X9341)    //非9341,尝试看看是不是NT35310
+    {
+        LCD_WR_REG(0XD4);
+        lcddev.id = LCD_RD_DATA(); //dummy read
+        lcddev.id = LCD_RD_DATA(); //读回0X01
+        lcddev.id = LCD_RD_DATA(); //读回0X53
+        lcddev.id <<= 8;
+        lcddev.id |= LCD_RD_DATA(); //这里读回0X10
+        if (lcddev.id != 0X5310)    //也不是NT35310,尝试看看是不是NT35510
+        {
+            LCD_WR_REG(0XDA00);
+            lcddev.id = LCD_RD_DATA(); //读回0X00
+            LCD_WR_REG(0XDB00);
+            lcddev.id = LCD_RD_DATA(); //读回0X80
+            lcddev.id <<= 8;
+            LCD_WR_REG(0XDC00);
+            lcddev.id |= LCD_RD_DATA(); //读回0X00
+            if (lcddev.id == 0x8000)
+                lcddev.id = 0x5510;  //NT35510读回的ID是8000H,为方便区分,我们强制设置为5510
+            if (lcddev.id != 0X5510) //也不是NT5510,尝试看看是不是SSD1963
+            {
+                LCD_WR_REG(0XA1);
+                lcddev.id = LCD_RD_DATA();
+                lcddev.id = LCD_RD_DATA(); //读回0X57
+                lcddev.id <<= 8;
+                lcddev.id |= LCD_RD_DATA(); //读回0X61
+                if (lcddev.id == 0X5761)
+                    lcddev.id = 0X1963; //SSD1963读回的ID是5761H,为方便区分,我们强制设置为1963
+            }
+        }
+    }
+    LOG_I(" LCD ID:%x", lcddev.id); //打印LCD ID
+    if (lcddev.id == 0X9341)        //9341初始化
+    {
+        LCD_WR_REG(0xCF);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC1);
+        LCD_WR_DATA(0X30);
+        LCD_WR_REG(0xED);
+        LCD_WR_DATA(0x64);
+        LCD_WR_DATA(0x03);
+        LCD_WR_DATA(0X12);
+        LCD_WR_DATA(0X81);
+        LCD_WR_REG(0xE8);
+        LCD_WR_DATA(0x85);
+        LCD_WR_DATA(0x10);
+        LCD_WR_DATA(0x7A);
+        LCD_WR_REG(0xCB);
+        LCD_WR_DATA(0x39);
+        LCD_WR_DATA(0x2C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x34);
+        LCD_WR_DATA(0x02);
+        LCD_WR_REG(0xF7);
+        LCD_WR_DATA(0x20);
+        LCD_WR_REG(0xEA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0xC0);  //Power control
+        LCD_WR_DATA(0x1B); //VRH[5:0]
+        LCD_WR_REG(0xC1);  //Power control
+        LCD_WR_DATA(0x01); //SAP[2:0];BT[3:0]
+        LCD_WR_REG(0xC5);  //VCM control
+        LCD_WR_DATA(0x30); //3F
+        LCD_WR_DATA(0x30); //3C
+        LCD_WR_REG(0xC7);  //VCM control2
+        LCD_WR_DATA(0XB7);
+        LCD_WR_REG(0x36); // Memory Access Control
+        LCD_WR_DATA(0x48);
+        LCD_WR_REG(0x3A);
+        LCD_WR_DATA(0x55);
+        LCD_WR_REG(0xB1);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1A);
+        LCD_WR_REG(0xB6); // Display Function Control
+        LCD_WR_DATA(0x0A);
+        LCD_WR_DATA(0xA2);
+        LCD_WR_REG(0xF2); // 3Gamma Function Disable
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0x26); //Gamma curve selected
+        LCD_WR_DATA(0x01);
+        LCD_WR_REG(0xE0); //Set Gamma
+        LCD_WR_DATA(0x0F);
+        LCD_WR_DATA(0x2A);
+        LCD_WR_DATA(0x28);
+        LCD_WR_DATA(0x08);
+        LCD_WR_DATA(0x0E);
+        LCD_WR_DATA(0x08);
+        LCD_WR_DATA(0x54);
+        LCD_WR_DATA(0XA9);
+        LCD_WR_DATA(0x43);
+        LCD_WR_DATA(0x0A);
+        LCD_WR_DATA(0x0F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0XE1); //Set Gamma
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x15);
+        LCD_WR_DATA(0x17);
+        LCD_WR_DATA(0x07);
+        LCD_WR_DATA(0x11);
+        LCD_WR_DATA(0x06);
+        LCD_WR_DATA(0x2B);
+        LCD_WR_DATA(0x56);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x05);
+        LCD_WR_DATA(0x10);
+        LCD_WR_DATA(0x0F);
+        LCD_WR_DATA(0x3F);
+        LCD_WR_DATA(0x3F);
+        LCD_WR_DATA(0x0F);
+        LCD_WR_REG(0x2B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0x3f);
+        LCD_WR_REG(0x2A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xef);
+        LCD_WR_REG(0x11); //Exit Sleep
+        rt_thread_mdelay(120);
+        LCD_WR_REG(0x29); //display on
+    }
+    else if (lcddev.id == 0x5310)
+    {
+        LCD_WR_REG(0xED);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0xFE);
+
+        LCD_WR_REG(0xEE);
+        LCD_WR_DATA(0xDE);
+        LCD_WR_DATA(0x21);
+
+        LCD_WR_REG(0xF1);
+        LCD_WR_DATA(0x01);
+        LCD_WR_REG(0xDF);
+        LCD_WR_DATA(0x10);
+
+        //VCOMvoltage//
+        LCD_WR_REG(0xC4);
+        LCD_WR_DATA(0x8F); //5f
+
+        LCD_WR_REG(0xC6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xE2);
+        LCD_WR_DATA(0xE2);
+        LCD_WR_DATA(0xE2);
+        LCD_WR_REG(0xBF);
+        LCD_WR_DATA(0xAA);
+
+        LCD_WR_REG(0xB0);
+        LCD_WR_DATA(0x0D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x0D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x11);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x19);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x21);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5D);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB1);
+        LCD_WR_DATA(0x80);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x8B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x96);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x02);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x03);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB4);
+        LCD_WR_DATA(0x8B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x96);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA1);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB5);
+        LCD_WR_DATA(0x02);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x03);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x04);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5E);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x64);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x8C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xAC);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDC);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x70);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x90);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xEB);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDC);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xB8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xBA);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC1);
+        LCD_WR_DATA(0x20);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x54);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xFF);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC2);
+        LCD_WR_DATA(0x0A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x04);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC3);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x39);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x37);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x36);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x32);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x29);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x26);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x23);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x36);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x32);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x29);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x26);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x24);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x23);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC4);
+        LCD_WR_DATA(0x62);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x05);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x84);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF0);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x18);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x18);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x50);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x0C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x17);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x95);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xE6);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC5);
+        LCD_WR_DATA(0x32);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x65);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x76);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC6);
+        LCD_WR_DATA(0x20);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x17);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xC9);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE0);
+        LCD_WR_DATA(0x16);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x21);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x36);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x46);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x52);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x64);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x7A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x8B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB9);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xCA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD9);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xE0);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE1);
+        LCD_WR_DATA(0x16);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x22);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x36);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x45);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x52);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x64);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x7A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x8B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB9);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xCA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xE0);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE2);
+        LCD_WR_DATA(0x05);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x0B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x34);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x4F);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x61);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x79);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x97);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD1);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0xE3);
+        LCD_WR_DATA(0x05);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x1C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x33);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x50);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x62);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x78);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x97);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA6);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC7);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD1);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD5);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE4);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x01);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x02);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x2A);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x4B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x74);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x84);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x93);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBE);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xCD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0xE5);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x02);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x29);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x3C);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x4B);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x5D);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x74);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x84);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x93);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xA2);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xB3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBE);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xC4);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xCD);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xD3);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xDC);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE6);
+        LCD_WR_DATA(0x11);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x34);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x56);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x76);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x77);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBB);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x45);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x43);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE7);
+        LCD_WR_DATA(0x32);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x76);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x67);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x67);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x87);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBB);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x77);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x56);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x23);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x33);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x45);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE8);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x87);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x77);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x88);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xAA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0xBB);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x99);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x66);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x44);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x55);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xE9);
+        LCD_WR_DATA(0xAA);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0x00);
+        LCD_WR_DATA(0xAA);
+
+        LCD_WR_REG(0xCF);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xF0);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x50);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xF3);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xF9);
+        LCD_WR_DATA(0x06);
+        LCD_WR_DATA(0x10);
+        LCD_WR_DATA(0x29);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0x3A);
+        LCD_WR_DATA(0x55); //66
+
+        LCD_WR_REG(0x11);
+        rt_thread_mdelay(100);
+        LCD_WR_REG(0x29);
+        LCD_WR_REG(0x35);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0x51);
+        LCD_WR_DATA(0xFF);
+        LCD_WR_REG(0x53);
+        LCD_WR_DATA(0x2C);
+        LCD_WR_REG(0x55);
+        LCD_WR_DATA(0x82);
+        LCD_WR_REG(0x2c);
+    }
+    else if (lcddev.id == 0x5510)
+    {
+        LCD_WriteReg(0xF000, 0x55);
+        LCD_WriteReg(0xF001, 0xAA);
+        LCD_WriteReg(0xF002, 0x52);
+        LCD_WriteReg(0xF003, 0x08);
+        LCD_WriteReg(0xF004, 0x01);
+        //AVDD Set AVDD 5.2V
+        LCD_WriteReg(0xB000, 0x0D);
+        LCD_WriteReg(0xB001, 0x0D);
+        LCD_WriteReg(0xB002, 0x0D);
+        //AVDD ratio
+        LCD_WriteReg(0xB600, 0x34);
+        LCD_WriteReg(0xB601, 0x34);
+        LCD_WriteReg(0xB602, 0x34);
+        //AVEE -5.2V
+        LCD_WriteReg(0xB100, 0x0D);
+        LCD_WriteReg(0xB101, 0x0D);
+        LCD_WriteReg(0xB102, 0x0D);
+        //AVEE ratio
+        LCD_WriteReg(0xB700, 0x34);
+        LCD_WriteReg(0xB701, 0x34);
+        LCD_WriteReg(0xB702, 0x34);
+        //VCL -2.5V
+        LCD_WriteReg(0xB200, 0x00);
+        LCD_WriteReg(0xB201, 0x00);
+        LCD_WriteReg(0xB202, 0x00);
+        //VCL ratio
+        LCD_WriteReg(0xB800, 0x24);
+        LCD_WriteReg(0xB801, 0x24);
+        LCD_WriteReg(0xB802, 0x24);
+        //VGH 15V (Free pump)
+        LCD_WriteReg(0xBF00, 0x01);
+        LCD_WriteReg(0xB300, 0x0F);
+        LCD_WriteReg(0xB301, 0x0F);
+        LCD_WriteReg(0xB302, 0x0F);
+        //VGH ratio
+        LCD_WriteReg(0xB900, 0x34);
+        LCD_WriteReg(0xB901, 0x34);
+        LCD_WriteReg(0xB902, 0x34);
+        //VGL_REG -10V
+        LCD_WriteReg(0xB500, 0x08);
+        LCD_WriteReg(0xB501, 0x08);
+        LCD_WriteReg(0xB502, 0x08);
+        LCD_WriteReg(0xC200, 0x03);
+        //VGLX ratio
+        LCD_WriteReg(0xBA00, 0x24);
+        LCD_WriteReg(0xBA01, 0x24);
+        LCD_WriteReg(0xBA02, 0x24);
+        //VGMP/VGSP 4.5V/0V
+        LCD_WriteReg(0xBC00, 0x00);
+        LCD_WriteReg(0xBC01, 0x78);
+        LCD_WriteReg(0xBC02, 0x00);
+        //VGMN/VGSN -4.5V/0V
+        LCD_WriteReg(0xBD00, 0x00);
+        LCD_WriteReg(0xBD01, 0x78);
+        LCD_WriteReg(0xBD02, 0x00);
+        //VCOM
+        LCD_WriteReg(0xBE00, 0x00);
+        LCD_WriteReg(0xBE01, 0x64);
+        //Gamma Setting
+        LCD_WriteReg(0xD100, 0x00);
+        LCD_WriteReg(0xD101, 0x33);
+        LCD_WriteReg(0xD102, 0x00);
+        LCD_WriteReg(0xD103, 0x34);
+        LCD_WriteReg(0xD104, 0x00);
+        LCD_WriteReg(0xD105, 0x3A);
+        LCD_WriteReg(0xD106, 0x00);
+        LCD_WriteReg(0xD107, 0x4A);
+        LCD_WriteReg(0xD108, 0x00);
+        LCD_WriteReg(0xD109, 0x5C);
+        LCD_WriteReg(0xD10A, 0x00);
+        LCD_WriteReg(0xD10B, 0x81);
+        LCD_WriteReg(0xD10C, 0x00);
+        LCD_WriteReg(0xD10D, 0xA6);
+        LCD_WriteReg(0xD10E, 0x00);
+        LCD_WriteReg(0xD10F, 0xE5);
+        LCD_WriteReg(0xD110, 0x01);
+        LCD_WriteReg(0xD111, 0x13);
+        LCD_WriteReg(0xD112, 0x01);
+        LCD_WriteReg(0xD113, 0x54);
+        LCD_WriteReg(0xD114, 0x01);
+        LCD_WriteReg(0xD115, 0x82);
+        LCD_WriteReg(0xD116, 0x01);
+        LCD_WriteReg(0xD117, 0xCA);
+        LCD_WriteReg(0xD118, 0x02);
+        LCD_WriteReg(0xD119, 0x00);
+        LCD_WriteReg(0xD11A, 0x02);
+        LCD_WriteReg(0xD11B, 0x01);
+        LCD_WriteReg(0xD11C, 0x02);
+        LCD_WriteReg(0xD11D, 0x34);
+        LCD_WriteReg(0xD11E, 0x02);
+        LCD_WriteReg(0xD11F, 0x67);
+        LCD_WriteReg(0xD120, 0x02);
+        LCD_WriteReg(0xD121, 0x84);
+        LCD_WriteReg(0xD122, 0x02);
+        LCD_WriteReg(0xD123, 0xA4);
+        LCD_WriteReg(0xD124, 0x02);
+        LCD_WriteReg(0xD125, 0xB7);
+        LCD_WriteReg(0xD126, 0x02);
+        LCD_WriteReg(0xD127, 0xCF);
+        LCD_WriteReg(0xD128, 0x02);
+        LCD_WriteReg(0xD129, 0xDE);
+        LCD_WriteReg(0xD12A, 0x02);
+        LCD_WriteReg(0xD12B, 0xF2);
+        LCD_WriteReg(0xD12C, 0x02);
+        LCD_WriteReg(0xD12D, 0xFE);
+        LCD_WriteReg(0xD12E, 0x03);
+        LCD_WriteReg(0xD12F, 0x10);
+        LCD_WriteReg(0xD130, 0x03);
+        LCD_WriteReg(0xD131, 0x33);
+        LCD_WriteReg(0xD132, 0x03);
+        LCD_WriteReg(0xD133, 0x6D);
+        LCD_WriteReg(0xD200, 0x00);
+        LCD_WriteReg(0xD201, 0x33);
+        LCD_WriteReg(0xD202, 0x00);
+        LCD_WriteReg(0xD203, 0x34);
+        LCD_WriteReg(0xD204, 0x00);
+        LCD_WriteReg(0xD205, 0x3A);
+        LCD_WriteReg(0xD206, 0x00);
+        LCD_WriteReg(0xD207, 0x4A);
+        LCD_WriteReg(0xD208, 0x00);
+        LCD_WriteReg(0xD209, 0x5C);
+        LCD_WriteReg(0xD20A, 0x00);
+
+        LCD_WriteReg(0xD20B, 0x81);
+        LCD_WriteReg(0xD20C, 0x00);
+        LCD_WriteReg(0xD20D, 0xA6);
+        LCD_WriteReg(0xD20E, 0x00);
+        LCD_WriteReg(0xD20F, 0xE5);
+        LCD_WriteReg(0xD210, 0x01);
+        LCD_WriteReg(0xD211, 0x13);
+        LCD_WriteReg(0xD212, 0x01);
+        LCD_WriteReg(0xD213, 0x54);
+        LCD_WriteReg(0xD214, 0x01);
+        LCD_WriteReg(0xD215, 0x82);
+        LCD_WriteReg(0xD216, 0x01);
+        LCD_WriteReg(0xD217, 0xCA);
+        LCD_WriteReg(0xD218, 0x02);
+        LCD_WriteReg(0xD219, 0x00);
+        LCD_WriteReg(0xD21A, 0x02);
+        LCD_WriteReg(0xD21B, 0x01);
+        LCD_WriteReg(0xD21C, 0x02);
+        LCD_WriteReg(0xD21D, 0x34);
+        LCD_WriteReg(0xD21E, 0x02);
+        LCD_WriteReg(0xD21F, 0x67);
+        LCD_WriteReg(0xD220, 0x02);
+        LCD_WriteReg(0xD221, 0x84);
+        LCD_WriteReg(0xD222, 0x02);
+        LCD_WriteReg(0xD223, 0xA4);
+        LCD_WriteReg(0xD224, 0x02);
+        LCD_WriteReg(0xD225, 0xB7);
+        LCD_WriteReg(0xD226, 0x02);
+        LCD_WriteReg(0xD227, 0xCF);
+        LCD_WriteReg(0xD228, 0x02);
+        LCD_WriteReg(0xD229, 0xDE);
+        LCD_WriteReg(0xD22A, 0x02);
+        LCD_WriteReg(0xD22B, 0xF2);
+        LCD_WriteReg(0xD22C, 0x02);
+        LCD_WriteReg(0xD22D, 0xFE);
+        LCD_WriteReg(0xD22E, 0x03);
+        LCD_WriteReg(0xD22F, 0x10);
+        LCD_WriteReg(0xD230, 0x03);
+        LCD_WriteReg(0xD231, 0x33);
+        LCD_WriteReg(0xD232, 0x03);
+        LCD_WriteReg(0xD233, 0x6D);
+        LCD_WriteReg(0xD300, 0x00);
+        LCD_WriteReg(0xD301, 0x33);
+        LCD_WriteReg(0xD302, 0x00);
+        LCD_WriteReg(0xD303, 0x34);
+        LCD_WriteReg(0xD304, 0x00);
+        LCD_WriteReg(0xD305, 0x3A);
+        LCD_WriteReg(0xD306, 0x00);
+        LCD_WriteReg(0xD307, 0x4A);
+        LCD_WriteReg(0xD308, 0x00);
+        LCD_WriteReg(0xD309, 0x5C);
+        LCD_WriteReg(0xD30A, 0x00);
+
+        LCD_WriteReg(0xD30B, 0x81);
+        LCD_WriteReg(0xD30C, 0x00);
+        LCD_WriteReg(0xD30D, 0xA6);
+        LCD_WriteReg(0xD30E, 0x00);
+        LCD_WriteReg(0xD30F, 0xE5);
+        LCD_WriteReg(0xD310, 0x01);
+        LCD_WriteReg(0xD311, 0x13);
+        LCD_WriteReg(0xD312, 0x01);
+        LCD_WriteReg(0xD313, 0x54);
+        LCD_WriteReg(0xD314, 0x01);
+        LCD_WriteReg(0xD315, 0x82);
+        LCD_WriteReg(0xD316, 0x01);
+        LCD_WriteReg(0xD317, 0xCA);
+        LCD_WriteReg(0xD318, 0x02);
+        LCD_WriteReg(0xD319, 0x00);
+        LCD_WriteReg(0xD31A, 0x02);
+        LCD_WriteReg(0xD31B, 0x01);
+        LCD_WriteReg(0xD31C, 0x02);
+        LCD_WriteReg(0xD31D, 0x34);
+        LCD_WriteReg(0xD31E, 0x02);
+        LCD_WriteReg(0xD31F, 0x67);
+        LCD_WriteReg(0xD320, 0x02);
+        LCD_WriteReg(0xD321, 0x84);
+        LCD_WriteReg(0xD322, 0x02);
+        LCD_WriteReg(0xD323, 0xA4);
+        LCD_WriteReg(0xD324, 0x02);
+        LCD_WriteReg(0xD325, 0xB7);
+        LCD_WriteReg(0xD326, 0x02);
+        LCD_WriteReg(0xD327, 0xCF);
+        LCD_WriteReg(0xD328, 0x02);
+        LCD_WriteReg(0xD329, 0xDE);
+        LCD_WriteReg(0xD32A, 0x02);
+        LCD_WriteReg(0xD32B, 0xF2);
+        LCD_WriteReg(0xD32C, 0x02);
+        LCD_WriteReg(0xD32D, 0xFE);
+        LCD_WriteReg(0xD32E, 0x03);
+        LCD_WriteReg(0xD32F, 0x10);
+        LCD_WriteReg(0xD330, 0x03);
+        LCD_WriteReg(0xD331, 0x33);
+        LCD_WriteReg(0xD332, 0x03);
+        LCD_WriteReg(0xD333, 0x6D);
+        LCD_WriteReg(0xD400, 0x00);
+        LCD_WriteReg(0xD401, 0x33);
+        LCD_WriteReg(0xD402, 0x00);
+        LCD_WriteReg(0xD403, 0x34);
+        LCD_WriteReg(0xD404, 0x00);
+        LCD_WriteReg(0xD405, 0x3A);
+        LCD_WriteReg(0xD406, 0x00);
+        LCD_WriteReg(0xD407, 0x4A);
+        LCD_WriteReg(0xD408, 0x00);
+        LCD_WriteReg(0xD409, 0x5C);
+        LCD_WriteReg(0xD40A, 0x00);
+        LCD_WriteReg(0xD40B, 0x81);
+
+        LCD_WriteReg(0xD40C, 0x00);
+        LCD_WriteReg(0xD40D, 0xA6);
+        LCD_WriteReg(0xD40E, 0x00);
+        LCD_WriteReg(0xD40F, 0xE5);
+        LCD_WriteReg(0xD410, 0x01);
+        LCD_WriteReg(0xD411, 0x13);
+        LCD_WriteReg(0xD412, 0x01);
+        LCD_WriteReg(0xD413, 0x54);
+        LCD_WriteReg(0xD414, 0x01);
+        LCD_WriteReg(0xD415, 0x82);
+        LCD_WriteReg(0xD416, 0x01);
+        LCD_WriteReg(0xD417, 0xCA);
+        LCD_WriteReg(0xD418, 0x02);
+        LCD_WriteReg(0xD419, 0x00);
+        LCD_WriteReg(0xD41A, 0x02);
+        LCD_WriteReg(0xD41B, 0x01);
+        LCD_WriteReg(0xD41C, 0x02);
+        LCD_WriteReg(0xD41D, 0x34);
+        LCD_WriteReg(0xD41E, 0x02);
+        LCD_WriteReg(0xD41F, 0x67);
+        LCD_WriteReg(0xD420, 0x02);
+        LCD_WriteReg(0xD421, 0x84);
+        LCD_WriteReg(0xD422, 0x02);
+        LCD_WriteReg(0xD423, 0xA4);
+        LCD_WriteReg(0xD424, 0x02);
+        LCD_WriteReg(0xD425, 0xB7);
+        LCD_WriteReg(0xD426, 0x02);
+        LCD_WriteReg(0xD427, 0xCF);
+        LCD_WriteReg(0xD428, 0x02);
+        LCD_WriteReg(0xD429, 0xDE);
+        LCD_WriteReg(0xD42A, 0x02);
+        LCD_WriteReg(0xD42B, 0xF2);
+        LCD_WriteReg(0xD42C, 0x02);
+        LCD_WriteReg(0xD42D, 0xFE);
+        LCD_WriteReg(0xD42E, 0x03);
+        LCD_WriteReg(0xD42F, 0x10);
+        LCD_WriteReg(0xD430, 0x03);
+        LCD_WriteReg(0xD431, 0x33);
+        LCD_WriteReg(0xD432, 0x03);
+        LCD_WriteReg(0xD433, 0x6D);
+        LCD_WriteReg(0xD500, 0x00);
+        LCD_WriteReg(0xD501, 0x33);
+        LCD_WriteReg(0xD502, 0x00);
+        LCD_WriteReg(0xD503, 0x34);
+        LCD_WriteReg(0xD504, 0x00);
+        LCD_WriteReg(0xD505, 0x3A);
+        LCD_WriteReg(0xD506, 0x00);
+        LCD_WriteReg(0xD507, 0x4A);
+        LCD_WriteReg(0xD508, 0x00);
+        LCD_WriteReg(0xD509, 0x5C);
+        LCD_WriteReg(0xD50A, 0x00);
+        LCD_WriteReg(0xD50B, 0x81);
+
+        LCD_WriteReg(0xD50C, 0x00);
+        LCD_WriteReg(0xD50D, 0xA6);
+        LCD_WriteReg(0xD50E, 0x00);
+        LCD_WriteReg(0xD50F, 0xE5);
+        LCD_WriteReg(0xD510, 0x01);
+        LCD_WriteReg(0xD511, 0x13);
+        LCD_WriteReg(0xD512, 0x01);
+        LCD_WriteReg(0xD513, 0x54);
+        LCD_WriteReg(0xD514, 0x01);
+        LCD_WriteReg(0xD515, 0x82);
+        LCD_WriteReg(0xD516, 0x01);
+        LCD_WriteReg(0xD517, 0xCA);
+        LCD_WriteReg(0xD518, 0x02);
+        LCD_WriteReg(0xD519, 0x00);
+        LCD_WriteReg(0xD51A, 0x02);
+        LCD_WriteReg(0xD51B, 0x01);
+        LCD_WriteReg(0xD51C, 0x02);
+        LCD_WriteReg(0xD51D, 0x34);
+        LCD_WriteReg(0xD51E, 0x02);
+        LCD_WriteReg(0xD51F, 0x67);
+        LCD_WriteReg(0xD520, 0x02);
+        LCD_WriteReg(0xD521, 0x84);
+        LCD_WriteReg(0xD522, 0x02);
+        LCD_WriteReg(0xD523, 0xA4);
+        LCD_WriteReg(0xD524, 0x02);
+        LCD_WriteReg(0xD525, 0xB7);
+        LCD_WriteReg(0xD526, 0x02);
+        LCD_WriteReg(0xD527, 0xCF);
+        LCD_WriteReg(0xD528, 0x02);
+        LCD_WriteReg(0xD529, 0xDE);
+        LCD_WriteReg(0xD52A, 0x02);
+        LCD_WriteReg(0xD52B, 0xF2);
+        LCD_WriteReg(0xD52C, 0x02);
+        LCD_WriteReg(0xD52D, 0xFE);
+        LCD_WriteReg(0xD52E, 0x03);
+        LCD_WriteReg(0xD52F, 0x10);
+        LCD_WriteReg(0xD530, 0x03);
+        LCD_WriteReg(0xD531, 0x33);
+        LCD_WriteReg(0xD532, 0x03);
+        LCD_WriteReg(0xD533, 0x6D);
+        LCD_WriteReg(0xD600, 0x00);
+        LCD_WriteReg(0xD601, 0x33);
+        LCD_WriteReg(0xD602, 0x00);
+        LCD_WriteReg(0xD603, 0x34);
+        LCD_WriteReg(0xD604, 0x00);
+        LCD_WriteReg(0xD605, 0x3A);
+        LCD_WriteReg(0xD606, 0x00);
+        LCD_WriteReg(0xD607, 0x4A);
+        LCD_WriteReg(0xD608, 0x00);
+        LCD_WriteReg(0xD609, 0x5C);
+        LCD_WriteReg(0xD60A, 0x00);
+        LCD_WriteReg(0xD60B, 0x81);
+
+        LCD_WriteReg(0xD60C, 0x00);
+        LCD_WriteReg(0xD60D, 0xA6);
+        LCD_WriteReg(0xD60E, 0x00);
+        LCD_WriteReg(0xD60F, 0xE5);
+        LCD_WriteReg(0xD610, 0x01);
+        LCD_WriteReg(0xD611, 0x13);
+        LCD_WriteReg(0xD612, 0x01);
+        LCD_WriteReg(0xD613, 0x54);
+        LCD_WriteReg(0xD614, 0x01);
+        LCD_WriteReg(0xD615, 0x82);
+        LCD_WriteReg(0xD616, 0x01);
+        LCD_WriteReg(0xD617, 0xCA);
+        LCD_WriteReg(0xD618, 0x02);
+        LCD_WriteReg(0xD619, 0x00);
+        LCD_WriteReg(0xD61A, 0x02);
+        LCD_WriteReg(0xD61B, 0x01);
+        LCD_WriteReg(0xD61C, 0x02);
+        LCD_WriteReg(0xD61D, 0x34);
+        LCD_WriteReg(0xD61E, 0x02);
+        LCD_WriteReg(0xD61F, 0x67);
+        LCD_WriteReg(0xD620, 0x02);
+        LCD_WriteReg(0xD621, 0x84);
+        LCD_WriteReg(0xD622, 0x02);
+        LCD_WriteReg(0xD623, 0xA4);
+        LCD_WriteReg(0xD624, 0x02);
+        LCD_WriteReg(0xD625, 0xB7);
+        LCD_WriteReg(0xD626, 0x02);
+        LCD_WriteReg(0xD627, 0xCF);
+        LCD_WriteReg(0xD628, 0x02);
+        LCD_WriteReg(0xD629, 0xDE);
+        LCD_WriteReg(0xD62A, 0x02);
+        LCD_WriteReg(0xD62B, 0xF2);
+        LCD_WriteReg(0xD62C, 0x02);
+        LCD_WriteReg(0xD62D, 0xFE);
+        LCD_WriteReg(0xD62E, 0x03);
+        LCD_WriteReg(0xD62F, 0x10);
+        LCD_WriteReg(0xD630, 0x03);
+        LCD_WriteReg(0xD631, 0x33);
+        LCD_WriteReg(0xD632, 0x03);
+        LCD_WriteReg(0xD633, 0x6D);
+        //LV2 Page 0 enable
+        LCD_WriteReg(0xF000, 0x55);
+        LCD_WriteReg(0xF001, 0xAA);
+        LCD_WriteReg(0xF002, 0x52);
+        LCD_WriteReg(0xF003, 0x08);
+        LCD_WriteReg(0xF004, 0x00);
+        //Display control
+        LCD_WriteReg(0xB100, 0xCC);
+        LCD_WriteReg(0xB101, 0x00);
+        //Source hold time
+        LCD_WriteReg(0xB600, 0x05);
+        //Gate EQ control
+        LCD_WriteReg(0xB700, 0x70);
+        LCD_WriteReg(0xB701, 0x70);
+        //Source EQ control (Mode 2)
+        LCD_WriteReg(0xB800, 0x01);
+        LCD_WriteReg(0xB801, 0x03);
+        LCD_WriteReg(0xB802, 0x03);
+        LCD_WriteReg(0xB803, 0x03);
+        //Inversion mode (2-dot)
+        LCD_WriteReg(0xBC00, 0x02);
+        LCD_WriteReg(0xBC01, 0x00);
+        LCD_WriteReg(0xBC02, 0x00);
+        //Timing control 4H w/ 4-delay
+        LCD_WriteReg(0xC900, 0xD0);
+        LCD_WriteReg(0xC901, 0x02);
+        LCD_WriteReg(0xC902, 0x50);
+        LCD_WriteReg(0xC903, 0x50);
+        LCD_WriteReg(0xC904, 0x50);
+        LCD_WriteReg(0x3500, 0x00);
+        LCD_WriteReg(0x3A00, 0x55); //16-bit/pixel
+        LCD_WR_REG(0x1100);
+        rt_thread_mdelay(1);
+        LCD_WR_REG(0x2900);
+    }
+    else if (lcddev.id == 0X1963)
+    {
+        LCD_WR_REG(0xE2);  //Set PLL with OSC = 10MHz (hardware),	Multiplier N = 35, 250MHz < VCO < 800MHz = OSC*(N+1), VCO = 300MHz
+        LCD_WR_DATA(0x1D); //参数1
+        LCD_WR_DATA(0x02); //参数2 Divider M = 2, PLL = 300/(M+1) = 100MHz
+        LCD_WR_DATA(0x04); //参数3 Validate M and N values
+        rt_thread_mdelay(1);
+        LCD_WR_REG(0xE0);  // Start PLL command
+        LCD_WR_DATA(0x01); // enable PLL
+        rt_thread_mdelay(10);
+        LCD_WR_REG(0xE0);  // Start PLL command again
+        LCD_WR_DATA(0x03); // now, use PLL output as system clock
+        rt_thread_mdelay(12);
+        LCD_WR_REG(0x01); //软复位
+        rt_thread_mdelay(10);
+
+        LCD_WR_REG(0xE6); //设置像素频率,33Mhz
+        LCD_WR_DATA(0x2F);
+        LCD_WR_DATA(0xFF);
+        LCD_WR_DATA(0xFF);
+
+        LCD_WR_REG(0xB0);  //设置LCD模式
+        LCD_WR_DATA(0x20); //24位模式
+        LCD_WR_DATA(0x00); //TFT 模式
+
+        LCD_WR_DATA((SSD_HOR_RESOLUTION - 1) >> 8); //设置LCD水平像素
+        LCD_WR_DATA(SSD_HOR_RESOLUTION - 1);
+        LCD_WR_DATA((SSD_VER_RESOLUTION - 1) >> 8); //设置LCD垂直像素
+        LCD_WR_DATA(SSD_VER_RESOLUTION - 1);
+        LCD_WR_DATA(0x00); //RGB序列
+
+        LCD_WR_REG(0xB4); //Set horizontal period
+        LCD_WR_DATA((SSD_HT - 1) >> 8);
+        LCD_WR_DATA(SSD_HT - 1);
+        LCD_WR_DATA(SSD_HPS >> 8);
+        LCD_WR_DATA(SSD_HPS);
+        LCD_WR_DATA(SSD_HOR_PULSE_WIDTH - 1);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+        LCD_WR_REG(0xB6); //Set vertical period
+        LCD_WR_DATA((SSD_VT - 1) >> 8);
+        LCD_WR_DATA(SSD_VT - 1);
+        LCD_WR_DATA(SSD_VPS >> 8);
+        LCD_WR_DATA(SSD_VPS);
+        LCD_WR_DATA(SSD_VER_FRONT_PORCH - 1);
+        LCD_WR_DATA(0x00);
+        LCD_WR_DATA(0x00);
+
+        LCD_WR_REG(0xF0);  //设置SSD1963与CPU接口为16bit
+        LCD_WR_DATA(0x03); //16-bit(565 format) data for 16bpp
+
+        LCD_WR_REG(0x29); //开启显示
+        //设置PWM输出  背光通过占空比可调
+        LCD_WR_REG(0xD0);  //设置自动白平衡DBC
+        LCD_WR_DATA(0x00); //disable
+
+        LCD_WR_REG(0xBE);  //配置PWM输出
+        LCD_WR_DATA(0x05); //1设置PWM频率
+        LCD_WR_DATA(0xFE); //2设置PWM占空比
+        LCD_WR_DATA(0x01); //3设置C
+        LCD_WR_DATA(0x00); //4设置D
+        LCD_WR_DATA(0x00); //5设置E
+        LCD_WR_DATA(0x00); //6设置F
+
+        LCD_WR_REG(0xB8);  //设置GPIO配置
+        LCD_WR_DATA(0x03); //2个IO口设置成输出
+        LCD_WR_DATA(0x01); //GPIO使用正常的IO功能
+        LCD_WR_REG(0xBA);
+        LCD_WR_DATA(0X01); //GPIO[1:0]=01,控制LCD方向
+
+        LCD_SSD_BackLightSet(100); //背光设置为最亮
+    }
+    //初始化完成以后,提速
+    if (lcddev.id == 0X9341 || lcddev.id == 0X5310 || lcddev.id == 0X5510 || lcddev.id == 0X1963) //如果是这几个IC,则设置WR时序为最快
+    {
+        //重新配置写时序控制寄存器的时序
+        FSMC_Bank1E->BWTR[6] &= ~(0XF << 0); //地址建立时间(ADDSET)清零
+        FSMC_Bank1E->BWTR[6] &= ~(0XF << 8); //数据保存时间清零
+        FSMC_Bank1E->BWTR[6] |= 3 << 0;      //地址建立时间(ADDSET)为3个HCLK =18ns
+        FSMC_Bank1E->BWTR[6] |= 2 << 8;      //数据保存时间(DATAST)为6ns*3个HCLK=18ns
+    }
+    LCD_Display_Dir(1); //默认为横屏
+
+    rt_pin_write(LCD_BL, PIN_HIGH);
+
+    LCD_Clear(0xffff);
+
+    return RT_EOK;
+}
+
+struct rt_device_graphic_ops fsmc_lcd_ops =
+    {
+        LCD_Fast_DrawPoint,
+        LCD_ReadPoint,
+        LCD_HLine,
+        RT_NULL,
+        LCD_BlitLine,
+};
+
+static rt_err_t drv_lcd_control(struct rt_device *device, int cmd, void *args)
+{
+    struct drv_lcd_device *lcd = LCD_DEVICE(device);
+    switch (cmd)
+    {
+    case RTGRAPHIC_CTRL_GET_INFO:
+    {
+        struct rt_device_graphic_info *info = (struct rt_device_graphic_info *)args;
+
+        RT_ASSERT(info != RT_NULL);
+
+        //this needs to be replaced by the customer
+        info->pixel_format  = lcd->lcd_info.pixel_format;
+        info->bits_per_pixel = lcd->lcd_info.bits_per_pixel;
+        info->width = lcddev.width;
+        info->height = lcddev.height;
+    }
+    break;
+    }
+
+    return RT_EOK;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops lcd_ops =
+    {
+        drv_lcd_init,
+        RT_NULL,
+        RT_NULL,
+        RT_NULL,
+        RT_NULL,
+        drv_lcd_control};
+#endif
+
+int drv_lcd_hw_init(void)
+{
+    rt_err_t result = RT_EOK;
+    struct rt_device *device = &_lcd.parent;
+    /* memset _lcd to zero */
+    memset(&_lcd, 0x00, sizeof(_lcd));
+
+    _lcd.lcd_info.bits_per_pixel = 16;
+    _lcd.lcd_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
+
+    device->type = RT_Device_Class_Graphic;
+#ifdef RT_USING_DEVICE_OPS
+    device->ops = &lcd_ops;
+#else
+    device->init = drv_lcd_init;
+    device->control = drv_lcd_control;
+#endif
+    device->user_data = &fsmc_lcd_ops;
+    /* register lcd device */
+    rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
+
+    return result;
+}
+INIT_DEVICE_EXPORT(drv_lcd_hw_init);
+
+#ifdef BSP_USING_MCU_LCD_TEST
+void lcd_auto_fill(void *para)
+{
+    int num = (int)para;
+    do
+    {
+        LCD_Clear(rt_tick_get());
+        rt_thread_mdelay(500);
+    }while(--num);
+}
+
+#include <stdlib.h> /* atoi */
+void lcd_fill(int argc, void **argv)
+{
+    static rt_uint8_t lcd_init = 0;
+    rt_device_t lcd = RT_NULL;
+
+    if(lcd_init == 0)
+    {
+        lcd_init = 1;
+
+        lcd = rt_device_find("lcd");
+        rt_device_init(lcd);
+    }
+
+    if(argc == 1)
+    {
+        lcd_auto_fill((void *)1);
+    }
+    else if(argc == 3)
+    {
+        if(rt_strcmp(argv[1], "-t")==0)
+        {
+            rt_thread_t tid = RT_NULL;
+            tid = rt_thread_create("lcd_fill", lcd_auto_fill, (void *)atoi(argv[2]), 512, 23,10);
+            rt_thread_startup(tid);
+        }
+    }
+}
+MSH_CMD_EXPORT(lcd_fill, lcd fill test for mcu lcd);
+#endif

+ 74 - 0
bsp/stm32/stm32f407-atk-explorer/board/ports/drv_lcd.h

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-12-28     unknow       copy by STemwin
+ */
+#ifndef __DRV_LCD_H
+#define __DRV_LCD_H
+#include <rtthread.h>
+#include "rtdevice.h"
+#include <drv_common.h>
+
+#define LCD_W 800
+#define LCD_H 480
+
+
+//LCD重要参数集
+typedef struct
+{
+	uint16_t width;			//LCD 宽度
+	uint16_t height;			//LCD 高度
+	uint16_t id;				//LCD ID
+	uint8_t  dir;			//横屏还是竖屏控制:0,竖屏;1,横屏。
+	uint16_t wramcmd;		//开始写gram指令
+	uint16_t setxcmd;		//设置x坐标指令
+	uint16_t setycmd;		//设置y坐标指令
+}_lcd_dev;
+
+//LCD参数
+extern _lcd_dev lcddev;	//管理LCD重要参数
+
+typedef struct
+{
+  __IO uint16_t REG;
+  __IO uint16_t RAM;
+}LCD_CONTROLLER_TypeDef;
+
+//扫描方向定义
+#define L2R_U2D  0 		//从左到右,从上到下
+#define L2R_D2U  1 		//从左到右,从下到上
+#define R2L_U2D  2 		//从右到左,从上到下
+#define R2L_D2U  3 		//从右到左,从下到上
+
+#define U2D_L2R  4 		//从上到下,从左到右
+#define U2D_R2L  5 		//从上到下,从右到左
+#define D2U_L2R  6 		//从下到上,从左到右
+#define D2U_R2L  7		//从下到上,从右到左
+
+#define DFT_SCAN_DIR  L2R_U2D  //默认的扫描方向
+
+//LCD分辨率设置
+#define SSD_HOR_RESOLUTION		800		//LCD水平分辨率
+#define SSD_VER_RESOLUTION		480		//LCD垂直分辨率
+//LCD驱动参数设置
+#define SSD_HOR_PULSE_WIDTH		1		//水平脉宽
+#define SSD_HOR_BACK_PORCH		46		//水平前廊
+#define SSD_HOR_FRONT_PORCH		210		//水平后廊
+
+#define SSD_VER_PULSE_WIDTH		1		//垂直脉宽
+#define SSD_VER_BACK_PORCH		23		//垂直前廊
+#define SSD_VER_FRONT_PORCH		22		//垂直前廊
+//如下几个参数,自动计算
+#define SSD_HT	(SSD_HOR_RESOLUTION+SSD_HOR_BACK_PORCH+SSD_HOR_FRONT_PORCH)
+#define SSD_HPS	(SSD_HOR_BACK_PORCH)
+#define SSD_VT 	(SSD_VER_RESOLUTION+SSD_VER_BACK_PORCH+SSD_VER_FRONT_PORCH)
+#define SSD_VPS (SSD_VER_BACK_PORCH)
+
+
+void lcd_fill_array(rt_uint16_t x_start, rt_uint16_t y_start, rt_uint16_t x_end, rt_uint16_t y_end, void *pcolor);
+
+#endif

+ 208 - 0
bsp/stm32/stm32f407-atk-explorer/board/ports/touch/drv_touch.c

@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     Zhangyihong  the first version
+ */
+
+#include "drv_touch.h"
+#include <string.h>
+#ifdef BSP_USING_TOUCH
+#ifdef PKG_USING_GUIENGINE
+#include <rtgui/event.h>
+#include <rtgui/rtgui_server.h>
+#elif defined(PKG_USING_LITTLEVGL2RTT)
+#include <littlevgl2rtt.h>
+#elif defined(PKG_USING_LVGL)
+#include <lvgl.h>
+#include <lv_port_indev.h>
+static rt_bool_t touch_down = RT_FALSE;
+#endif
+#define BSP_TOUCH_SAMPLE_HZ    (50)
+
+#define DBG_ENABLE
+#define DBG_SECTION_NAME  "TOUCH"
+#define DBG_LEVEL         DBG_INFO
+#define DBG_COLOR
+#include <rtdbg.h>
+
+static rt_list_t driver_list;
+
+
+void rt_touch_drivers_register(touch_drv_t drv)
+{
+    rt_list_insert_before(&driver_list, &drv->list);
+}
+
+static void post_down_event(rt_uint16_t x, rt_uint16_t y, rt_tick_t ts)
+{
+#ifdef PKG_USING_GUIENGINE
+    struct rtgui_event_mouse emouse;
+
+    emouse.parent.sender = RT_NULL;
+    emouse.wid = RT_NULL;
+
+    emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
+    emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
+    emouse.x = x;
+    emouse.y = y;
+    emouse.ts = rt_tick_get();
+    emouse.id = ts;
+    rtgui_server_post_event(&emouse.parent, sizeof(emouse));
+#elif defined(PKG_USING_LITTLEVGL2RTT)
+    littlevgl2rtt_send_input_event(x, y, LITTLEVGL2RTT_INPUT_DOWN);
+#elif defined(PKG_USING_LVGL)
+    touch_down = RT_TRUE;
+    lv_port_indev_input(x, y, (touch_down == RT_TRUE) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL);
+#endif
+}
+
+static void post_motion_event(rt_uint16_t x, rt_uint16_t y, rt_tick_t ts)
+{
+#ifdef PKG_USING_GUIENGINE
+    struct rtgui_event_mouse emouse;
+
+    emouse.parent.sender = RT_NULL;
+    emouse.wid = RT_NULL;
+
+    emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
+    emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
+    emouse.x = x;
+    emouse.y = y;
+    emouse.ts = rt_tick_get();
+    emouse.id = ts;
+    rtgui_server_post_event(&emouse.parent, sizeof(emouse));
+#elif defined(PKG_USING_LITTLEVGL2RTT)
+    littlevgl2rtt_send_input_event(x, y, LITTLEVGL2RTT_INPUT_MOVE);
+#elif defined(PKG_USING_LVGL)
+    lv_port_indev_input(x, y, (touch_down == RT_TRUE) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL);
+#endif
+}
+
+static void post_up_event(rt_uint16_t x, rt_uint16_t y, rt_tick_t ts)
+{
+#ifdef PKG_USING_GUIENGINE
+    struct rtgui_event_mouse emouse;
+
+    emouse.parent.sender = RT_NULL;
+    emouse.wid = RT_NULL;
+
+    emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
+    emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP;
+    emouse.x = x;
+    emouse.y = y;
+    emouse.ts = rt_tick_get();
+    emouse.id = ts;
+    rtgui_server_post_event(&emouse.parent, sizeof(emouse));
+#elif defined(PKG_USING_LITTLEVGL2RTT)
+    littlevgl2rtt_send_input_event(x, y, LITTLEVGL2RTT_INPUT_MOVE);
+#elif defined(PKG_USING_LVGL)
+    touch_down = RT_FALSE;
+    lv_port_indev_input(x, y, (touch_down == RT_TRUE) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL);
+#endif
+}
+
+static void touch_thread_entry(void *parameter)
+{
+    touch_drv_t touch = (touch_drv_t)parameter;
+    struct touch_message msg;
+    rt_tick_t emouse_id = 0;
+    touch->ops->isr_enable(RT_TRUE);
+    while (1)
+    {
+        if (rt_sem_take(touch->isr_sem, 10) != RT_EOK)
+        {
+            continue;
+        }
+
+        while(touch->ops->read_point(&msg) == RT_EOK)
+        {
+            switch (msg.event)
+            {
+            case TOUCH_EVENT_UP:
+                post_up_event(msg.x, msg.y, emouse_id);
+                break;
+            case TOUCH_EVENT_DOWN:
+                emouse_id = rt_tick_get();
+                post_down_event(msg.x, msg.y, emouse_id);
+                break;
+            case TOUCH_EVENT_MOVE:
+                post_motion_event(msg.x, msg.y, emouse_id);
+                break;
+            default:
+                break;
+            }
+            rt_thread_delay(RT_TICK_PER_SECOND / BSP_TOUCH_SAMPLE_HZ);
+        }
+        touch->ops->isr_enable(RT_TRUE);
+    }
+}
+
+static int rt_touch_driver_init(void)
+{
+    rt_list_init(&driver_list);
+    return 0;
+}
+INIT_BOARD_EXPORT(rt_touch_driver_init);
+
+static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
+static int rt_touch_thread_init(void)
+{
+    rt_list_t *l;
+    touch_drv_t current_driver;
+    rt_thread_t tid = RT_NULL;
+    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find("i2c2");
+    RT_ASSERT(i2c_bus);
+    current_driver = RT_NULL;
+    if (rt_device_open((rt_device_t)i2c_bus, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
+        return -1;
+    for (l = driver_list.next; l != &driver_list; l = l->next)
+    {
+        if (rt_list_entry(l, struct touch_drivers, list)->probe(i2c_bus))
+        {
+            current_driver = rt_list_entry(l, struct touch_drivers, list);
+            break;
+        }
+    }
+    if (current_driver == RT_NULL)
+    {
+        LOG_E("no touch screen or do not have driver");
+        rt_device_close((rt_device_t)i2c_bus);
+        return -1;
+    }
+    current_driver->ops->init(i2c_bus);
+    LOG_I("touch screen found driver");
+    tid = rt_thread_create("touch", touch_thread_entry, current_driver, 2048, 27, 20);
+    if (tid == RT_NULL)
+    {
+        current_driver->ops->deinit();
+        rt_device_close((rt_device_t)i2c_bus);
+        return -1;
+    }
+    rt_thread_startup(tid);
+    return 0;
+}
+
+static void touch_init_thread_entry(void *parameter)
+{
+    rt_touch_thread_init();
+}
+
+static int touc_bg_init(void)
+{
+    rt_thread_t tid = RT_NULL;
+    tid = rt_thread_create("touchi", touch_init_thread_entry, RT_NULL, 2048, 28, 20);
+    if (tid == RT_NULL)
+    {
+        return -1;
+    }
+    rt_thread_startup(tid);
+    return 0;
+}
+INIT_APP_EXPORT(touc_bg_init);
+
+
+#endif

+ 55 - 0
bsp/stm32/stm32f407-atk-explorer/board/ports/touch/drv_touch.h

@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-02-08     Zhangyihong  the first version
+ */
+
+#ifndef __DRV_TOUCH_H__
+#define __DRV_TOUCH_H__
+
+#include "rtthread.h"
+#include "rtdevice.h"
+
+#define TOUCH_DBG_LEVEL DBG_INFO
+
+#define IIC_RETRY_NUM 2
+
+#define TOUCH_EVENT_UP      (0x01)
+#define TOUCH_EVENT_DOWN    (0x02)
+#define TOUCH_EVENT_MOVE    (0x03)
+#define TOUCH_EVENT_NONE    (0x80)
+
+struct touch_message
+{
+    rt_uint16_t x;
+    rt_uint16_t y;
+    rt_uint8_t event;
+};
+typedef struct touch_message *touch_msg_t;
+
+struct touch_ops
+{
+    void (* isr_enable)(rt_bool_t);
+    rt_err_t (* read_point)(touch_msg_t);
+    void (* init)(struct rt_i2c_bus_device *);
+    void (* deinit)(void);
+};
+typedef struct touch_ops *touch_ops_t;
+
+struct touch_drivers
+{
+    rt_list_t       list;
+    unsigned char   address;
+    rt_bool_t (*probe)(struct rt_i2c_bus_device *i2c_bus);
+    rt_sem_t        isr_sem;
+    touch_ops_t     ops;
+    void           *user_data;
+};
+typedef struct touch_drivers *touch_drv_t;
+
+extern void rt_touch_drivers_register(touch_drv_t drv);
+#endif

+ 240 - 0
bsp/stm32/stm32f407-atk-explorer/board/ports/touch/drv_touch_ft.c

@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author        Notes
+ * 2017-08-08     Yang          the first version
+ * 2019-04-23     WillianChan   porting to ft6206
+ * 2021-12-28     xiangxistu    copy by stm32f429-atk-apollo
+ * 2021-04-23     xiangxistu    porting to GT9147
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+#include "drv_touch.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#ifdef BSP_USING_TOUCH
+
+#define DBG_ENABLE
+#define DBG_SECTION_NAME  "TOUCH.ft"
+#define DBG_LEVEL         TOUCH_DBG_LEVEL
+#define DBG_COLOR
+#include <rtdbg.h>
+
+static struct rt_i2c_bus_device *ft_i2c_bus;
+static struct touch_drivers ft_driver;
+
+static int ft_read(struct rt_i2c_bus_device *i2c_bus, rt_uint16_t addr, rt_uint8_t *buffer, rt_size_t length)
+{
+    int ret = -1;
+    int retries = 0;
+    rt_uint8_t register_16[3];
+    register_16[0] = addr >> 8;
+    register_16[1] = addr & 0xff;
+
+    struct rt_i2c_msg msgs[] =
+    {
+        {
+            .addr   = ft_driver.address,
+            .flags  = RT_I2C_WR,
+            .len    = 2,
+            .buf    = register_16,
+        },
+        {
+            .addr   = ft_driver.address,
+            .flags  = RT_I2C_RD,
+            .len    = length,
+            .buf    = buffer,
+        },
+    };
+
+    while (retries < IIC_RETRY_NUM)
+    {
+        ret = rt_i2c_transfer(i2c_bus, msgs, sizeof(msgs)/sizeof(struct rt_i2c_msg));
+        if (ret == 2)break;
+        retries++;
+    }
+
+    if (retries >= IIC_RETRY_NUM)
+    {
+        LOG_E("%s i2c read error: %d", __func__, ret);
+        return -1;
+    }
+
+    return ret;
+}
+
+static void ft_write(struct rt_i2c_bus_device *i2c_bus, rt_uint16_t addr, rt_uint8_t *buffer, rt_size_t length)
+{
+    rt_uint8_t *send_buffer = rt_malloc(length + 2);
+
+    RT_ASSERT(send_buffer);
+
+    send_buffer[0] = addr >> 8;;
+    send_buffer[1] = addr & 0xff;
+    memcpy(send_buffer + 2, buffer, length);
+
+    struct rt_i2c_msg msgs[] =
+    {
+        {
+            .addr   = ft_driver.address,
+            .flags  = RT_I2C_WR,
+            .len    = length + 2,
+            .buf    = send_buffer,
+        }
+    };
+
+    length = rt_i2c_transfer(i2c_bus, msgs, 1);
+    rt_free(send_buffer);
+    send_buffer = RT_NULL;
+}
+
+static void ft_isr_enable(rt_bool_t enable)
+{
+    rt_pin_irq_enable(BSP_TOUCH_INT_PIN, enable);
+}
+
+static void ft_touch_isr(void *parameter)
+{
+    ft_isr_enable(RT_FALSE);
+    rt_sem_release(ft_driver.isr_sem);
+}
+
+static rt_err_t ft_read_point(touch_msg_t msg)
+{
+    int ret = -1;
+    uint8_t state = 0;
+    uint8_t clear_state = 0;
+    static uint8_t s_tp_down = 0;
+    uint8_t point[5];
+    ret = ft_read(ft_i2c_bus, 0X814E, &state, 1);
+    if (ret < 0)
+    {
+        return RT_ERROR;
+    }
+
+    /* According this state, to get point info */
+    if(state&0X80&&((state&0XF)<6))
+    {
+        clear_state = 0;
+        ft_write(ft_i2c_bus, 0X814E, &clear_state, 1);
+    }
+    else
+    {
+        if (s_tp_down)
+        {
+            s_tp_down = 0;
+            msg->event = TOUCH_EVENT_UP;
+            return RT_EOK;
+        }
+        msg->event = TOUCH_EVENT_NONE;
+        return RT_ERROR;
+    }
+
+    /* Only support one point */
+    ret = ft_read(ft_i2c_bus, 0X8150, point, 4);
+    if (ret < 0)
+    {
+        return RT_ERROR;
+    }
+
+    msg->x = (point[1]&0x0F) << 8 | point[0];
+    msg->y = (point[3]&0x0F) << 8 | point[2];
+    LOG_D("x:%03d, y:%03d", msg->x, msg->y);
+
+    if (s_tp_down)
+    {
+        msg->event = TOUCH_EVENT_MOVE;
+        return RT_EOK;
+    }
+    msg->event = TOUCH_EVENT_DOWN;
+    s_tp_down = 1;
+
+    return RT_EOK;
+}
+
+static void ft_init(struct rt_i2c_bus_device *i2c_bus)
+{
+    if (ft_i2c_bus == RT_NULL)
+    {
+        ft_i2c_bus = i2c_bus;
+    }
+    ft_driver.isr_sem = rt_sem_create("ft", 0, RT_IPC_FLAG_FIFO);
+    RT_ASSERT(ft_driver.isr_sem);
+
+    rt_pin_mode(BSP_TOUCH_INT_PIN, PIN_MODE_INPUT_PULLUP);
+    rt_pin_attach_irq(BSP_TOUCH_INT_PIN, PIN_IRQ_MODE_FALLING, ft_touch_isr, RT_NULL);
+
+    rt_thread_mdelay(200);
+}
+
+static void ft_deinit(void)
+{
+    if (ft_driver.isr_sem)
+    {
+        rt_sem_delete(ft_driver.isr_sem);
+        ft_driver.isr_sem = RT_NULL;
+    }
+}
+
+struct touch_ops ft_ops =
+{
+    ft_isr_enable,
+    ft_read_point,
+    ft_init,
+    ft_deinit,
+};
+
+static rt_bool_t ft_probe(struct rt_i2c_bus_device *i2c_bus)
+{
+#define TOUCH_CID_SIZE 4
+    int err = 0;
+    uint8_t cid[TOUCH_CID_SIZE + 1] = {0};
+
+    ft_i2c_bus = i2c_bus;
+    /* FT6206 Chip identification register address is 0xA8
+     *
+     * GT9147 ->  0X8140, CID
+     *
+     **/
+    rt_memset(cid, 0, TOUCH_CID_SIZE + 1);
+    err = ft_read(ft_i2c_bus, 0X8140, (uint8_t *)&cid, TOUCH_CID_SIZE);
+    if (err < 0)
+    {
+        LOG_E("%s failed: %d", __func__, err);
+        return RT_FALSE;
+    }
+    LOG_I("touch CID:0x%c%c%c%c", cid[0], cid[1], cid[2], cid[3]);
+
+    /* FT6206 ID Value is 0x11
+     * GT9147 ID will be 0x9147
+     */
+    if(rt_strncmp((char *)cid, "9147", TOUCH_CID_SIZE) == 0x0)
+    {
+        return RT_TRUE;
+    }
+    return RT_FALSE;
+}
+
+int ft_driver_register(void)
+{
+    /* TouchScreen FT6206 Slave I2C address is 0x54
+     * 0x54 << 1 = 0x2A
+     * 0x5D, 0x14  ------>   GT9147
+     */
+    ft_driver.address = 0x14;
+    ft_driver.probe = ft_probe;
+    ft_driver.ops = &ft_ops;
+    ft_driver.user_data = RT_NULL;
+    rt_touch_drivers_register(&ft_driver);
+    return 0;
+}
+INIT_DEVICE_EXPORT(ft_driver_register);
+
+#endif

+ 29 - 52
bsp/stm32/stm32f407-atk-explorer/rtconfig.h

@@ -1,7 +1,8 @@
 #ifndef RT_CONFIG_H__
 #define RT_CONFIG_H__
 
-/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */
+/* Automatically generated file; DO NOT EDIT. */
+/* RT-Thread Configuration */
 
 /* RT-Thread Kernel */
 
@@ -18,7 +19,6 @@
 
 /* kservice optimization */
 
-/* end of kservice optimization */
 #define RT_DEBUG
 #define RT_DEBUG_COLOR
 
@@ -29,7 +29,6 @@
 #define RT_USING_EVENT
 #define RT_USING_MAILBOX
 #define RT_USING_MESSAGEQUEUE
-/* end of Inter-Thread communication */
 
 /* Memory Management */
 
@@ -37,7 +36,6 @@
 #define RT_USING_SMALL_MEM
 #define RT_USING_SMALL_MEM_AS_HEAP
 #define RT_USING_HEAP
-/* end of Memory Management */
 
 /* Kernel Device Object */
 
@@ -45,9 +43,7 @@
 #define RT_USING_CONSOLE
 #define RT_CONSOLEBUF_SIZE 128
 #define RT_CONSOLE_DEVICE_NAME "uart1"
-/* end of Kernel Device Object */
 #define RT_VER_NUM 0x40100
-/* end of RT-Thread Kernel */
 #define ARCH_ARM
 #define RT_USING_CPU_FFS
 #define ARCH_ARM_CORTEX_M
@@ -62,7 +58,6 @@
 
 /* C++ features */
 
-/* end of C++ features */
 
 /* Command shell */
 
@@ -79,25 +74,26 @@
 #define MSH_USING_BUILT_IN_COMMANDS
 #define FINSH_USING_DESCRIPTION
 #define FINSH_ARG_MAX 10
-/* end of Command shell */
 
 /* Device virtual file system */
 
-/* end of Device virtual file system */
 
 /* Device Drivers */
 
 #define RT_USING_DEVICE_IPC
+#define RT_USING_SYSTEM_WORKQUEUE
+#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048
+#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
 #define RT_USING_SERIAL
 #define RT_USING_SERIAL_V1
 #define RT_SERIAL_USING_DMA
 #define RT_SERIAL_RB_BUFSZ 64
+#define RT_USING_I2C
+#define RT_USING_I2C_BITOPS
 #define RT_USING_PIN
 
 /* Using USB */
 
-/* end of Using USB */
-/* end of Device Drivers */
 
 /* POSIX layer and C standard library */
 
@@ -112,41 +108,28 @@
 
 /* Socket is in the 'Network' category */
 
-/* end of Interprocess Communication (IPC) */
-/* end of POSIX (Portable Operating System Interface) layer */
-/* end of POSIX layer and C standard library */
-
 /* Network */
 
 /* Socket abstraction layer */
 
-/* end of Socket abstraction layer */
 
 /* Network interface device */
 
-/* end of Network interface device */
 
 /* light weight TCP/IP stack */
 
-/* end of light weight TCP/IP stack */
 
 /* AT commands */
 
-/* end of AT commands */
-/* end of Network */
 
 /* VBUS(Virtual Software BUS) */
 
-/* end of VBUS(Virtual Software BUS) */
 
 /* Utilities */
 
-/* end of Utilities */
-/* end of RT-Thread Components */
 
 /* RT-Thread Utestcases */
 
-/* end of RT-Thread Utestcases */
 
 /* RT-Thread online packages */
 
@@ -157,83 +140,72 @@
 
 /* Marvell WiFi */
 
-/* end of Marvell WiFi */
 
 /* Wiced WiFi */
 
-/* end of Wiced WiFi */
-/* end of Wi-Fi */
 
 /* IoT Cloud */
 
-/* end of IoT Cloud */
-/* end of IoT - internet of things */
 
 /* security packages */
 
-/* end of security packages */
 
 /* language packages */
 
-/* end of language packages */
 
 /* multimedia packages */
 
 /* LVGL: powerful and easy-to-use embedded GUI library */
 
-/* end of LVGL: powerful and easy-to-use embedded GUI library */
+#define PKG_USING_LVGL
+#define PKG_USING_LVGL_V810
+#define PKG_LVGL_VER_NUM 0x08010
+#define PKG_USING_LV_MUSIC_DEMO
+#define PKG_USING_LV_MUSIC_DEMO_LATEST_VERSION
 
 /* u8g2: a monochrome graphic library */
 
-/* end of u8g2: a monochrome graphic library */
 
 /* PainterEngine: A cross-platform graphics application framework written in C language */
 
-/* end of PainterEngine: A cross-platform graphics application framework written in C language */
-/* end of multimedia packages */
 
 /* tools packages */
 
-/* end of tools packages */
 
 /* system packages */
 
+
 /* enhanced kernel services */
 
-/* end of enhanced kernel services */
 
 /* acceleration: Assembly language or algorithmic acceleration packages */
 
-/* end of acceleration: Assembly language or algorithmic acceleration packages */
 
 /* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
 
-/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
 
 /* Micrium: Micrium software products porting for RT-Thread */
 
-/* end of Micrium: Micrium software products porting for RT-Thread */
-/* end of system packages */
 
 /* peripheral libraries and drivers */
 
-/* end of peripheral libraries and drivers */
 
 /* AI packages */
 
-/* end of AI packages */
 
 /* miscellaneous packages */
 
 /* samples: kernel and components samples */
 
-/* end of samples: kernel and components samples */
 
 /* entertainment: terminal games and other interesting software packages */
 
-/* end of entertainment: terminal games and other interesting software packages */
-/* end of miscellaneous packages */
-/* end of RT-Thread online packages */
+
+/* Privated Packages of RealThread */
+
+
+/* Network Utilities */
+
 #define SOC_FAMILY_STM32
 #define SOC_SERIES_STM32F4
 
@@ -244,22 +216,27 @@
 /* Onboard Peripheral Drivers */
 
 #define BSP_USING_USB_TO_USART
+#define BSP_USING_SRAM
+#define BSP_USING_MCU_LCD
+#define BSP_USING_MCU_LCD_TEST
+#define BSP_USING_TOUCH
+#define BSP_TOUCH_INT_PIN 17
 
 /* Enable File System */
 
-/* end of Enable File System */
-/* end of Onboard Peripheral Drivers */
 
 /* On-chip Peripheral Drivers */
 
 #define BSP_USING_GPIO
 #define BSP_USING_UART
 #define BSP_USING_UART1
-/* end of On-chip Peripheral Drivers */
+#define BSP_USING_I2C2
+#define BSP_I2C2_SCL_PIN 16
+#define BSP_I2C2_SDA_PIN 91
+#define BSP_USING_EXT_FMC_IO
+#define BSP_USING_FMC
 
 /* Board extended module Drivers */
 
-/* end of Board extended module Drivers */
-/* end of Hardware Drivers Config */
 
 #endif